為什么進行壓縮編碼?
- 視頻是由一幀幀的圖像組成(見實例)
-
比如一張Gif圖片其實就可以被分解成若干張單獨的圖片
1.gif -
分別出的圖片
2.png
-
- 未經壓縮的視頻的數據量巨大
- 比如:錄音一分鐘視頻, 需要多大的空間來保存了?
- 1> 為了不讓用戶感受到卡頓效果, 1秒鐘之內至少需要16幀畫面(正常開發通常會采集30幀)
- 2> 假如該視頻是一個1280*720分辨率的視頻(正常情況下會比這個大很多)
- 結果:1280_720_16*60≈843.75M
- 如果幀率更高、分辨率更高、加上音頻,那么一分鐘的視頻是多大呢?
- 結論:
- 不經過壓縮編碼的視頻,根本沒辦法保存,更何況網絡中的傳輸
- 視頻錄制完成后,要先編碼,再傳輸,在解碼,再播放(重現)
為什么視頻可以壓縮編碼?
-
存在冗余信息
- 空間冗余:圖像相鄰像素之間有較強的相關性
- 時間冗余:視頻序列的相鄰圖像之間內容相似
- 視覺冗余:人的視覺系統對某些細節不敏感
- 等等冗余信息
-
空間冗余
- 空間冗余是指在同一張圖像中,有很多像素點表示的信息是完全一樣的
- 如果對每一個像素進行單獨的存儲,必然會非常浪費空間,也完全沒有必要
-
如圖:
空間冗余.png
-
時間冗余
- 時間冗余是指多張圖像之間,有非常多的相關性,由于一些小運動造成了細小差別
- 如果對每張圖像進行單獨的像素存儲,在下一張圖片中又出現了相同的。那么相當于很多像素都存儲了多份,必然會非常浪費空間,也是完全沒有必要的
-
如圖:
時間冗余.jpg
-
視覺冗余
- 人類視覺系統HVS
- 對高頻信息不敏感
- 對高對比度更敏感
- 對亮度信息比色度信息更敏感
- 對運動的信息更敏感
- 數字視頻系統的設計應該考慮HVS的特點:
- 丟棄高頻信息,只編碼低頻信息
- 提高邊緣信息的主觀質量
- 降低色度的解析度
- 對感興趣區域(Region of Interesting,ROI)進行特殊處理
-
如圖:
視覺冗余.png
- 人類視覺系統HVS
-
結論:
- 經過一系列的去處冗余信息,可以大大的降低視頻的數據量
- 更利于視頻的保存、傳輸
- 去除冗余信息的過程,我們就稱之為壓縮編碼
壓縮編碼的標準
- 為什么需要視頻壓縮編碼標準
- 目前,我們已經非常清楚,視頻在存儲&傳輸過程中,存在非常多的冗余信息,我們需要去除這些冗余信息
- 但是,如果每個人按照自己的方式去編碼,那么當我們需要還原原始數據時,很難知道對方是如何編碼的
- 比如:某主播在斗魚采用iPhone手機進行直播,手機錄制了主播大量的畫面,為了便于傳輸,需要程序對視頻進行壓縮編碼,但是他想當然的按照自己的某種算法進行了壓縮,并且將數據傳遞給了服務器,服務器拿到數據之后,進行數據分發給了各個客戶端:Android、iOS、Win、Web、Mac等等客戶端,這個時候每個客戶端需要知道對方的壓縮算法,才能將數據進行還原,但是因為當時客戶端是想當然的就行壓縮編碼的,并且也不能保證他的方式效率,而且有一點誤差可能會造成畫面無法還原的后果。
- 因此,視頻編碼必須制定一個大家都認同的標準
- 標準化組織:
- ITU:International Telecommunications Union VECG:Video Coding Experts Group(國際電傳視訊聯盟)
- ISO:International Standards Organization MPEG:Motion Picture Experts Group(國際標準組織機構)
- H.26X系列(由ITU[國際電傳視訊聯盟]主導)
- H.261:主要在老的視頻會議和視頻電話產品中使用
- H.263:主要用在視頻會議、視頻電話和網絡視頻上
- H.264:H.264/MPEG-4第十部分,或稱AVC(Advanced Video Coding,高級視頻編碼),是一種視頻壓縮標準,一種被廣泛使用的高精度視頻的錄制、壓縮和發布格式。
- H.265:高效率視頻編碼(High Efficiency Video Coding,簡稱HEVC)是一種視頻壓縮標準,H.264/MPEG-4 AVC的繼任者。可支持4K分辨率甚至到超高畫質電視,最高分辨率可達到8192×4320(8K分辨率),這是目前發展的趨勢,尚未有大眾化編碼軟件出現
- MPEG系列(由ISO[國際標準組織機構]下屬的MPEG[運動圖象專家組]開發)
- MPEG-1第二部分:MPEG-1第二部分主要使用在VCD上,有些在線視頻也使用這種格式
- MPEG-2第二部分(MPEG-2第二部分等同于H.262,使用在DVD、SVCD和大多數數字視頻廣播系統中
- MPEG-4第二部分(MPEG-4第二部分標準可以使用在網絡傳輸、廣播和媒體存儲上。 *
- 其他系列:
- AMV · AVS · Bink · RealVideo · Theora · VC-1 · VP3 · VP6 · VP7 · VP8 · VP9 · WMV
編碼的常見流程
- 在進行當前信號編碼時,編碼器首先會產生對當前信號做預測的信號,稱作預測信號(predicted signal)
- 預測的方式:
- 時間上的預測(interprediction),亦即使用先前幀的信號做預測
- 空間上的預測 (intra prediction),亦即使用同一張幀之中相鄰像素的信號做預測
- 得到預測信號后,編碼器會將當前信號與預測信號相減得到殘余信號(residual signal),并只對殘余信號進行編碼
- 如此一來,可以去除一部份時間上或是空間上的冗余信息
- 編碼器并不會直接對殘余信號進行編碼,而是先將殘余信號經過變換(通常為離散余弦變換)然后量化以進一步去除空間上和感知上的冗余信息
- 量化后得到的量化系數會再透過熵編碼,去除統計上的冗余信息
目前應用最廣泛的H.264(AVC)
H264是新一代的編碼標準,以高壓縮高質量和支持多種網絡的流媒體傳輸著稱
-
個人理解:
- 在相鄰幾幅圖像畫面中,一般有差別的像素只有10%以內的點,亮度差值變化不超過2%,而色度差值的變化只有1%以內
- 所以對于一段變化不大圖像畫面,我們可以先編碼出一個完整的圖像幀A,隨后的B幀就不編碼全部圖像,只寫入與A幀的差別,這樣B幀的大小就只有完整幀的1/10或更小!
- B幀之后的C幀如果變化不大,我們可以繼續以參考B的方式編碼C幀,這樣循環下去。
- 這段圖像我們稱為一個序列:序列就是有相同特點的一段數據
- 當某個圖像與之前的圖像變化很大,無法參考前面的幀來生成,那我們就結束上一個序列,開始下一段序列
- 也就是對這個圖像生成一個完整幀A1,隨后的圖像就參考A1生成,只寫入與A1的差別內容。
-
在H264協議里定義了三種幀
- I幀:完整編碼的幀叫I幀
- P幀:參考之前的I幀生成的只包含差異部分編碼的幀叫P幀
- B幀:參考前后的幀編碼的幀叫B幀
-
H264采用的核心算法是幀內壓縮和幀間壓縮
- 幀內壓縮是生成I幀的算法
- 幀間壓縮是生成B幀和P幀的算法
-
H264的壓縮方法:
- 分組:把幾幀圖像分為一組(GOP,也就是一個序列),為防止運動變化,幀數不宜取多
- 定義幀:將每組內各幀圖像定義為三種類型,即I幀、B幀和P幀;
- 預測幀:以I幀做為基礎幀,以I幀預測P幀,再由I幀和P幀預測B幀;
- 數據傳輸:最后將I幀數據與預測的差值信息進行存儲和傳輸。
-
序列(GOP)
- 在H264中圖像以序列為單位進行組織,一個序列是一段圖像編碼后的數據流。
- 一個序列的第一個圖像叫做 IDR 圖像(立即刷新圖像),IDR 圖像都是 I 幀圖像。
- H.264 引入 IDR 圖像是為了解碼的重同步,當解碼器解碼到 IDR 圖像時,立即將參考幀隊列清空,將已解碼的數據全部輸出或拋棄,重新查找參數集,開始一個新的序列。
- 這樣,如果前一個序列出現重大錯誤,在這里可以獲得重新同步的機會。
- IDR圖像之后的圖像永遠不會使用IDR之前的圖像的數據來解碼。
- 一個序列就是一段內容差異不太大的圖像編碼后生成的一串數據流
- 當運動變化比較少時,一個序列可以很長,因為運動變化少就代表圖像畫面的內容變動很小,所以就可以編一個I幀,然后一直P幀、B幀了。
- 當運動變化多時,可能一個序列就比較短了,比如就包含一個I幀和3、4個P幀。
- 在視頻編碼序列中,GOP即Group of picture(圖像組),指兩個I幀之間的距離
-
I幀、P幀、B幀的預測方向
序列1.png -
I幀、P幀、B幀實際順序&編碼后順序
序列2.png
H264分層設計
- 分層設計
- H264算法在概念上分為兩層:視頻編碼層(VCL:Video Coding Layer)負責高效的視頻內容表示,網絡提取層(NAL:Network Abstraction Layer)負責以網絡所要求的恰當的方式對數據進行打包和傳送。
- 這樣,高效編碼和網絡友好性分別由VCL和NAL分別完成
- 而之前我們學習的編碼方式,都是屬于VCL層
- NAL設計目的:
- 根據不同的網絡把數據打包成相應的格式,將VCL產生的比特字符串適配到各種各樣的網絡和多元環境中。
- NAL的封裝方式:
- NAL是將每一幀數據寫入到一個NAL單元中,進行傳輸或存儲的
- NALU分為NAL頭和NAL體
- NALU頭通常為00 00 00 01,作為一個新的NALU的起始標識
- NALU體封裝著VCL編碼后的信息或者其他信息
- 封裝過程:
- I幀、P幀、B幀都是被封裝成一個或者多個NALU進行傳輸或者存儲的
- I幀開始之前也有非VCL的NAL單元,用于保存其他信息,比如:PPS、SPS
- PPS(Picture Parameter Sets):圖像參數集
- SPS(Sequence Parameter Set):序列參數集
- 在實際的H264數據幀中,往往幀前面帶有00 00 00 01 或 00 00 01分隔符,一般來說編碼器編出的首幀數據為PPS與SPS,接著為I幀,后續是B幀、P幀等數據
H264分層設計.png
編碼方式
- 編碼的方式有兩種:
- 硬編碼:使用非CPU進行編碼,如顯卡GPU、專用的DSP、FPGA、ASIC芯片等
- 軟編碼:使用CPU進行編碼,軟編碼通常使用:ffmpeg+x264
- ffmpeg:是一套開源的、用于對音視頻進行編碼&解碼&轉化計算機程序
- x264:x264是一種免費的、開源的、具有更優秀算法的H.264/MPEG-4 AVC視頻壓縮編碼方式
- 對比:(沒有對比就沒有傷害)
- 軟編碼:實現直接、簡單,參數調整方便,升級易,但CPU負載重,性能較硬編碼低
- 性能高,對CPU沒有壓力,但是對其他硬件要求較高(如GPU等)
- iOS中編碼方式:
- 在iOS8之前,蘋果并沒有開放硬編碼的接口,所以只能采用ffpeng+x624進行軟編碼
- 在iOS8之后,蘋果開放了接口,并且封裝了VideoToolBox&AudioToolbox兩個框架,分別用于對視頻&音頻進行硬編碼