1. 程式人生 > >音視訊入門H264&AAC

音視訊入門H264&AAC

音視訊基礎知識簡述:
錄影、錄音,實質上是一個壓縮採集到的影象或者音訊資料的過程,這個過程又稱為編碼,混合。那為什麼需要編碼(壓縮)呢?因為裝置採集到的音視訊資料太大了,如果不進行壓縮,佔用的空間太大,不利於傳輸等。
而播放視訊或者音訊檔案,實質上是一個解壓縮的過程,這個過程又稱為解碼。那為什麼又要解碼(解壓縮)呢?因為播放器播放需要的是音訊取樣資料、視訊畫素資料,通俗一點來說就是需要的是編碼之前的資料,所以需要解碼來獲取。

播放一個視訊檔案的流程如下:
在這裡插入圖片描述
編碼的目的:
位元速率如果為10Mb/s,代表1秒鐘有10M bit的視訊資料,對於YUV422格式的1080P視訊而言,一幀影象是1920x1080x2x8/1024/1024 = 31.64Mbit,1秒鐘30幀影象的話,則有949.2Mb/s,可見其資料量之大,不壓縮根本無法網上傳播,通常720P的視訊位元速率4Mb/s,1080P的位元速率6~8Mb/s,壓縮率都在100倍以上。
同理原始音訊取樣資料體積很大,一般情況下一首4分鐘的PCM格式的歌曲體積為:
4 * 60 * 44100 * 2 * 8 * 2 = 338.4Mbit = 1.41Mb/s
PS:這裡假定取樣率為44100,取樣精度為16bit。
而平時一首4分鐘的MP3歌曲體積一般在4MB左右。
如果是AAC編碼格式的歌曲,體積就更小。

常見的一些音視訊質量引數:位元速率
位元速率:影響體積,與體積成正比:位元速率越大,體積越大;位元速率越小,體積越小。位元速率就是資料傳輸時單位時間傳送的資料位數,一般我們用的單位是kbps即千位每秒。也就是取樣率(並不等同與取樣率,取樣率的單位是Hz,表示每秒取樣的次數),單位時間內取樣率越大,精度就越高,處理出來的檔案就越接近原始檔案,但是檔案體積與取樣率是成正比的,所以幾乎所有的編碼格式重視的都是如何用最低的位元速率達到最少的失真,圍繞這個核心衍生出來cbr(固定位元速率)與vbr(可變位元速率), “位元速率”就是失真度,位元速率越高越清晰,反之則畫面粗糙而多馬賽克。

常見的一些音視訊質量引數:幀率
幀率(FPS):影響畫面流暢度,與畫面流暢度成正比:幀率越大,畫面越流暢;幀率越小,畫面越有跳動感。如果位元速率為變數,則幀率也會影響體積,幀率越高,每秒鐘經過的畫面越多,需要的位元速率也越高,體積也越大。
幀率就是在1秒鐘時間裡傳輸的圖片的幀數,也可以理解為圖形處理器每秒鐘能夠重新整理幾次。每秒顯示的圖片數影響畫面流暢度,與畫面流暢度成正比:幀率越大,畫面越流暢;幀率越小,畫面越有跳動感。由於人類眼睛的特殊生理結構,如果所看畫面之幀率高於16的時候,就會認為是連貫的,此現象稱之為視覺暫留。並且當幀速達到一定數值後,再增長的話,人眼也不容易察覺到有明顯的流暢度提升了。

常見的一些音視訊質量引數:解析度
解析度:影響影象大小,與影象大小成正比:解析度越高,圖
像越大;解析度越低,影象越小。

常見的一些音視訊質量引數:GOP
關鍵幀的週期,也就是兩個IDR幀之間的距離,一個幀組的最大幀數,一般而
言,每一秒視訊至少需要使用 1 個關鍵幀。增加關鍵幀個數可改善質量,但是同時增加頻寬和網路負載。需要說明的是,通過提高GOP值來提高影象質量是有限度的,在遇到場景切換的情況時,H.264編碼器會自動強制插入一個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響應的時間也越長。

視訊編碼標準前世今生:
在這裡插入圖片描述

音訊編碼標準前世今生:
在這裡插入圖片描述

追本溯源:H264資料從哪裡來:

在這裡插入圖片描述
RGB與YUV的相互轉換:
在這裡插入圖片描述

RGB畫素結構分析:
在這裡插入圖片描述
在這裡插入圖片描述
YUV畫素結構分析:
黑點表示Y分量,空心圓圈表示畫素點的UV分量
在這裡插入圖片描述

H264編碼原理:
l 資料冗餘。例如如空間冗餘、時間冗餘、結構冗餘、資訊熵冗餘等,即影象的各畫素之間存在著很強的相關性。消除這些冗餘並不會導致資訊損失,屬於無失真壓縮。

l 視覺冗餘。人眼的一些特性比如亮度辨別閾值,視覺閾值,對亮度和色度的敏感度不同,使得在編碼的時候引入適量的誤差,也不會被察覺出來。可以利用人眼的視覺特性,以一定的客觀失真換取資料壓縮。這種壓縮屬於有失真壓縮。
數字視訊訊號的壓縮正是基於上述兩種條件,使得視訊資料量得以極大的壓縮,有利於傳輸和儲存。一般的數字視訊壓縮編碼方法都是混合編碼,即將變換編碼,運動估計和運動補償,以及熵編碼三種方式相結合來進行壓縮編碼。通常使用變換編碼來消去除影象的幀內冗餘,用運動估計和運動補償來去除影象的幀間冗餘,用熵編碼來進一步提高壓縮的效率。

H264編碼:I幀 P幀 B幀:
在這裡插入圖片描述
H264編碼:變換編碼:
變換編碼
變換編碼的作用是將空間域描述的影象訊號變換到頻率域,然後對變換後的係數進行編碼處理。一般來說,影象在空間上具有較強的相關性,變換到頻率域可以實現去相關和能量集中。常用的正交變換有離散傅立葉變換,離散餘弦變換等等。數字視訊壓縮過程中應用廣泛的是離散餘弦變換。

離散餘弦變換簡稱為DCT變換。它可以將LL的影象塊從空間域變換為頻率域。所以,在基於DCT的影象壓縮編碼過程中,首先需要將影象分成互不重疊的影象塊。假設一幀影象的大小為1280720,首先將其以網格狀的形式分成16090個尺寸為88的彼此沒有重疊的影象塊,接下來才能對每個影象塊進行DCT變換。
經過分塊以後,每個88點的影象塊被送入DCT編碼器,將88的影象塊從空間域變換為頻率域。下圖給出一個實際8*8的影象塊例子,圖中的數字代表了每個畫素的亮度值。從圖上可以看出,在這個影象塊中各個畫素亮度值比較均勻,特別是相鄰畫素亮度值變化不是很大,說明影象訊號具有很強的相關性。

H264編碼:熵編碼:
熵編碼是因編碼後的平均碼長接近信源熵值而得名。熵編碼多用可變字長編碼(VLC,Variable Length Coding)實現。其基本原理是對信源中出現概率大的符號賦予短碼,對於出現概率小的符號賦予長碼,從而在統計上獲得較短的平均碼長。可變字長編碼通常有霍夫曼編碼、算術編碼、遊程編碼等。其中游程編碼是一種十分簡單的壓縮方法,它的壓縮效率不高,但編碼、解碼速度快,仍被得到廣泛的應用,特別在變換編碼之後使用遊程編碼,有很好的效果。
首先要在量化器輸出直流係數後對緊跟其後的交流係數進行Z型掃描(如圖箭頭線所示)。Z型掃描將二維的量化係數轉換為一維的序列,並在此基礎上進行遊程編碼。最後再對遊程編碼後的資料進行另一種變長編碼,例如霍夫曼編碼。通過這種變長編碼,進一步提高編碼的效率。

H264編碼:運動估計和運動補償編碼:
運動估計和運動補償
運動估計(Motion Estimation)和運動補償(Motion Compensation)是消除影象序列時間方向相關性的有效手段。上文介紹的DCT變換、量化、熵編碼的方法是在一幀影象的基礎上進行,通過這些方法可以消除影象內部各畫素間在空間上的相關性。實際上影象訊號除了空間上的相關性之外,還有時間上的相關性。例如對於像新聞聯播這種背景靜止,畫面主體運動較小的數字視訊,每一幅畫面之間的區別很小,畫面之間的相關性很大。對於這種情況我們沒有必要對每一幀影象單獨進行編碼,而是可以只對相鄰視訊幀中變化的部分進行編碼,從而進一步減小資料量,這方面的工作是由運動估計和運動補償來實現的。

H264碼流傳輸:
H.264 基本流的結構
H.264的功能分為兩層,視訊編碼層(VCL)和網路提取層(NAL)VCL資料即被壓縮編碼後的視訊資料序列。在VCL資料要封裝到NAL單元中之後,才可以用來傳輸或儲存。
NAL單元格式[2] 表1所示:
表1 NAL單元格式
NAL頭 RBSP NAL頭 RBSP

H.264的碼流結構圖:

在這裡插入圖片描述

H264碼流引數解析:
起始碼: 每個NALU 前需新增起始碼:0x000001,用來指示一個 NALU的起始和終止位置。在這樣的機制下,*在碼流中檢測起始碼,作為一個NALU得起始標識,(如果實際資料中連續出現二個0時編碼器會在0後自動加上0x03,解碼時相反處理丟掉0x03,所以不用擔心NALU本身資料存在和起始碼一樣的資料)當檢測到下一個起始碼時,當前NALU結束。
NALU header: NALU 頭的格式如圖2 所示:

1.forbidden_bit: 禁止位,初始為0,當網路發現NAL單元有位元錯誤時可設定該位元為1,以便接收方糾錯或丟掉該單元。
2.nal_reference_bitnal重要性指示,標誌該NAL單元的重要性,值越大,越重要,解碼器在解碼處理不過來的時候,可以丟掉重要性為0的NALU。
3.TYPE:NAL型別

H264傳輸的協議有哪些:流媒體協議:

在這裡插入圖片描述
RTSP協議概述:

在這裡插入圖片描述
RTSP協議與HTTP協議的區別:
在這裡插入圖片描述

RTSP訊息互動過程:
在這裡插入圖片描述
在這裡插入圖片描述
抓包工具wireshark使用:
通過live555作為服務端,vlc作為客戶端抓取網路傳輸包進行分析
初步掌握wireshark的使用方法,此文不做分析,後續單獨寫一篇進行詳細講解。

H264傳輸協議:RTP:
RTP 協議是 IETF 在 1996 年提出的適合實時資料傳輸的新型協議。RTP 協議實際上是由實時傳輸協議RTP(Real-time Transport Protocol)和實時傳輸控制協議RTCP(Real-time Transport Control Protocol)兩部分組成。RTP 協議基於多播或單播網路為使用者提供連續媒體資料的實時傳輸服務;RTCP 協議是 RTP 協議的控制部分,用於實時監控資料傳輸質量,為系統提供擁塞控制和流控制。RTP 協議在RFC3550 中有詳細介紹。每一個 RTP 資料包都由固定包頭(Header )和載荷(Payload)兩個部分組成,其中包頭前12個位元組的含義是固定的,而載荷則可以是音訊或視訊資料。RTP 固定包頭的格式如圖1所示:
在這裡插入圖片描述
RTP協議格式解析:
其中比較關鍵的引數設定解釋如下:
(1)標示位(M ):1 位,該標示位的含義一般由具體的媒體應用框架(profile )定義, 目的在於標記處RTP 流中的重要事件。
(2)載荷型別(PT):7 位,用來指出RTP負載的具體格式。在RFC3551中,對常用的音視訊格式的RTP 傳輸載荷型別做了預設的取值規定,例如,型別2 表明該RTP資料包中承載的是用ITU G.721 演算法編碼的語音資料,採用頻率為 8000HZ,並且採用單聲道。
(3)序號:16 位,每傳送一個 RTP 資料包,序號加 1。接受者可以用它來檢測分組丟失和恢復分組順序。
(4)時間戳:32 位,時間戳表示了 RTP 資料分組中第一個位元組的取樣時間,反映出各RTP 包相對於時間戳初始值的偏差。對於RTP 傳送端而言,取樣時間必須來源於一個線性單調遞增的時鐘。

H.264 流媒體傳輸系統的實現:
前面分別討論了RTP 協議及H.264基本流的結構,那麼如何使用RTP協議來傳輸H.264視訊了?一個有效的辦法就是從H.264視訊中剝離出每個NALU,在每個NALU前新增相應的RTP包頭,然後將包含RTP 包頭和NALU 的資料包傳送出去。
一個完整的流媒體傳輸系統包含伺服器端和客戶端兩個部分[5][6]。對於伺服器端,其主要任務是讀取H.264 視訊,從碼流中分離出每個NALU 單元,分析NALU 的型別,設定相應的 RTP 包頭,封裝 RTP 資料包併發送。而對於客戶端來說,其主要任務則是接收 RTP資料包,從RTP 包中解析出NALU 單元,然後送至*進行解碼播放。該流媒體傳輸系統的框架如下圖所示。

在這裡插入圖片描述