1. 程式人生 > >《音視訊直播------視訊編碼》

《音視訊直播------視訊編碼》

視訊編碼介紹

為什麼進行壓縮編碼?

  • 視訊是由一幀幀的影象組成(見例項)
    • 比如一張Gif圖片其實就可以被分解成若干張單獨的圖片

    • 分別出的圖片

  • 未經壓縮的視訊的資料量巨大
    • 比如:錄音一分鐘視訊, 需要多大的空間來儲存了?
    • 1> 為了不讓使用者感受到卡頓效果, 1秒鐘之內至少需要16幀畫面(正常開發通常會採集30幀)
    • 2> 假如該視訊是一個1280*720解析度的視訊(正常情況下會比這個大很多)
    • 結果:128072016*60≈843.75M
    • 如果幀率更高、解析度更高、加上音訊,那麼一分鐘的視訊是多大呢?
  • 結論:
    • 不經過壓縮編碼的視訊,根本沒辦法儲存,更何況網路中的傳輸
    • 視訊錄製完成後,要先編碼,再傳輸,在解碼,再播放(重現)

為什麼視訊可以壓縮編碼?

  • 存在冗餘資訊
    • 空間冗餘:影象相鄰畫素之間有較強的相關性
    • 時間冗餘:視訊序列的相鄰影象之間內容相似
    • 視覺冗餘:人的視覺系統對某些細節不敏感
    • 等等冗餘資訊
  • 空間冗餘
    • 空間冗餘是指在同一張影象中,有很多畫素點表示的資訊是完全一樣的
    • 如果對每一個畫素進行單獨的儲存,必然會非常浪費空間,也完全沒有必要
    • 如圖:

  • 時間冗餘
    • 時間冗餘是指多張影象之間,有非常多的相關性,由於一些小運動造成了細小差別
    • 如果對每張影象進行單獨的畫素儲存,在下一張圖片中又出現了相同的。那麼相當於很多畫素都儲存了多份,必然會非常浪費空間,也是完全沒有必要的
    • 如圖:

  • 視覺冗餘
    • 人類視覺系統HVS
      • 對高頻資訊不敏感
      • 對高對比度更敏感
      • 對亮度資訊比色度資訊更敏感
      • 對運動的資訊更敏感
    • 數字視訊系統的設計應該考慮HVS的特點:
      • 丟棄高頻資訊,只編碼低頻資訊
      • 提高邊緣資訊的主觀質量
      • 降低色度的解析度
      • 對感興趣區域(Region of Interesting,ROI)進行特殊處理
    • 如圖:

  • 結論:
    • 經過一系列的去處冗餘資訊,可以大大的降低視訊的資料量
    • 更利於視訊的儲存、傳輸
    • 去除冗餘資訊的過程,我們就稱之為壓縮編碼

壓縮編碼的標準

  • 為什麼需要視訊壓縮編碼標準
    • 目前,我們已經非常清楚,視訊在儲存&傳輸過程中,存在非常多的冗餘資訊,我們需要去除這些冗餘資訊
    • 但是,如果每個人按照自己的方式去編碼,那麼當我們需要還原原始資料時,很難知道對方是如何編碼的
    • 比如:某主播在鬥魚採用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幀的預測方向

    • I幀、P幀、B幀實際順序&編碼後順序

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幀等資料

編碼方式

  • 編碼的方式有兩種:
    • 硬編碼:使用非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兩個框架,分別用於對視訊&音訊進行硬編碼