從0開始做播放器---編解碼基礎(chǔ)知識

注:參考自bilibili系列視頻,從0開始做播放器-第6章-圖像編碼的基礎(chǔ)概念(理論課)https://www.bilibili.com/video/BV1PK41157jz

常見編碼格式

視頻需要編碼,是因為采集來的原始視頻太大,一部720p的電影,存原始圖像就需要大約1T。所以需要編碼,把原始圖像壓縮,便于我們傳輸和存儲。

  • H264 誕生于2003年,是目前最常見的編碼方式
  • H265 是H264的繼任者,相比H264,H265性能更好,壓縮的更小,但是很耗硬件,很多硬件不支持;H265不能廣泛使用的另一個原因是,H5瀏覽器還不支持H265,主要H265專利費(fèi)比較貴。
  • VP8 由 Google 發(fā)布,Youtube和google在用
  • VP9 是VP8的繼任者,由 Google 發(fā)布,Youtube和google在用
  • AVS(Audio Video coding Standard)國產(chǎn),常見于政府項目,安防領(lǐng)域
  • AVS2 是AVS的繼任者,國產(chǎn),常見于政府項目,安防領(lǐng)域

H264

  • SPS 序列參數(shù)集

    • profile,定義基礎(chǔ)配置
    • 視頻長寬
  • PPS 圖像參數(shù)集

    • 碼流中熵編碼/解碼選擇的算法
  • 一般來說,編碼器編出的首幀數(shù)據(jù)為PPS和SPS,接著為I幀(注: 要想解碼一路流,必須先把SPS和PPS傳給解碼器。)(https://zhuanlan.zhihu.com/p/27896239SPS和PPS詳解)

  • I幀 關(guān)鍵幀,保存整個圖像的信息,自身可以通過視頻解壓算法解壓成一張單獨(dú)的完整的圖片。I幀圖像用于阻止誤差的累積和擴(kuò)散。在閉合式GOP中,每個GOP的第一個幀一定是I幀,且當(dāng)前GOP的數(shù)據(jù)不會參考前后GOP的數(shù)據(jù)。

  • P幀 前向預(yù)測幀,只記錄本幀與前一幀的差別

  • B幀 雙向預(yù)測幀,只記錄本幀與前一幀和后一幀的差別;B幀具有更高的壓縮率,但需要更多的緩沖時間以及更高的CPU占用率,因此B幀適合本地存儲以及視頻點(diǎn)播,而不適用對實(shí)時性要求較高的直播系統(tǒng)。

NALU,幀,slice,宏塊之間的關(guān)系

H264原始碼流(裸流)是由一個接一個NALU組成,H264分為兩個層面,VCL(視頻編碼層)和 NAL(網(wǎng)絡(luò)提取層)。

  • VCL(video coding)視頻編碼層:負(fù)責(zé)有效表示視頻數(shù)據(jù)的內(nèi)容;
  • NAL(network abstraction)網(wǎng)絡(luò)抽象層:負(fù)責(zé)格式化數(shù)據(jù)并提供頭信息,以保證數(shù)據(jù)適合各種信道和存儲介質(zhì)上的傳播。

H264結(jié)構(gòu)中,一個視頻圖像編碼后的數(shù)據(jù)叫做一幀(frame),一幀由一個片(slice)或多個片組成,一個片由一個或多個宏塊(MB)組成,一個宏塊由16x16的yuv數(shù)據(jù)組成。宏塊作為H264編碼的基本單位。
NALU是一種封裝的模組 ,一個Slice編碼之后被打包進(jìn)一個NALU,不過NALU除了容納Slice編碼的碼流外,還可以容納其他數(shù)據(jù),比如序列參數(shù)集SPS。所以nalu不一定是slice。
拓展:
那么為什么要設(shè)置片(slice)呢?
設(shè)置片(slice)的目的是為了限制誤碼的擴(kuò)散和傳輸,應(yīng)使編碼片相互間是獨(dú)立的。某片的預(yù)測不能以其他片中的宏塊為參考圖像,這樣某一片中的預(yù)測誤差才不會傳播到其他片中。

PTS和DTS

PTS:顯示時間戳,表示解碼后的幀顯示的時間
DTS:解碼時間戳,表示送入解碼器的順序

NALU (Network Abstract Layer Unit)

  • nalu type 如下圖,常用的是1,5,7,8。
    • 1是非IDR幀 有可能是I幀,P幀,B幀
    • 5是IDR幀,IDR幀一定是I幀,但I(xiàn)幀不一定是IDR幀。IDR幀前面通常會有SPS和PPS。
      IDR幀常用于流媒體,因為存成文件的話,SPS、PPS信息會存在文件頭,只存一次就可以,而流媒體,由于是網(wǎng)絡(luò)流,
      1.只發(fā)一次SPS我們無法保證服務(wù)器一定會接收到;
      2.就算第一次發(fā)SPS就接收到了,那也需要一直在服務(wù)器緩存;
      3.如果直播小姐姐切換了前后攝像頭,SPS和PPS就會變化,如果還用第一次接收到的SPS,就會出錯
      所以就需要IDR幀的存在,隔一段時間,就傳一下SPS和PPS。
    • 7是SPS 序列參數(shù)集
    • 8是PPS 圖像參數(shù)集
      image.png
  • 獲取nalu type
    start code后面一個字節(jié)的低5位,獲取方法:int naluType = nalu[4]0x1f,這里是常犯錯誤的地方。

H264的兩種存儲形態(tài)

Annex B

  • startCode NALU 以0001或001開頭
  • 防競爭字節(jié) 編碼時,slice數(shù)據(jù)里如果出現(xiàn)000,就插入0x3,這樣,slice里所有的 0001 ,就被轉(zhuǎn)換為 000 0x3 1;解碼時,將slice數(shù)據(jù)中000后面的0x3去掉,就可以還原數(shù)據(jù)。
  • 多用于網(wǎng)絡(luò)流媒體中,rtp,rtmp等

AVCC

  • 表示NALU長度的前綴,不定長,有時1字節(jié),有時2字節(jié),有時4字節(jié)
  • 防競爭字節(jié),同上,將000后面插入0x3,在AVCC中,由于沒有startCode,這個操作對于AVCC格式是沒有實(shí)際意義的,但是要遵從標(biāo)準(zhǔn),所以也這樣做了。遵從標(biāo)準(zhǔn),有助于不同存儲形態(tài)之間轉(zhuǎn)換。
  • 多用于文件存儲中,如mp4

GOP

GOP是畫面組,一個GOP是一組連續(xù)的畫面。
GOP結(jié)構(gòu)一般是:
I BBP BBP BBP BB I
增大圖片組能有效的減少編碼后的視頻體積,但是也會降低視頻質(zhì)量。

常見誤區(qū)

  1. 分辨率越大碼率越大嗎?
    不一定。碼率是單位時間內(nèi),傳輸?shù)木幋a后的數(shù)據(jù)位數(shù)。碼率約等于傳輸速率。
    碼率由什么決定:
  • 分辨率,影響較小
  • 畫面混亂程度,單幀圖像,混亂程度越高,同等質(zhì)量下,編碼后的數(shù)據(jù)量越大;圖像越簡單,編碼后的數(shù)據(jù)越小。
  • 畫面之間的變化量越大,編碼后的數(shù)據(jù)量越大。
  • 編碼(壓縮)程度,畫面混亂程度相等時,壓縮的狠,畫質(zhì)可能不好,但編碼后數(shù)據(jù)會小
  1. P幀一定比I幀小,B幀一定比P幀小
  • P幀不一定比I幀小,當(dāng)場景轉(zhuǎn)換的時候,臨界兩幀,比如前一幀是室內(nèi)簡單場景,是I幀,后一幀是室外復(fù)雜場景,是P幀,P幀存的是與前一幀的變化量,場景轉(zhuǎn)換時,前后兩幀差距太大,P幀數(shù)據(jù)量就會很大。所以P幀不一定比I幀小。
  • B幀不一定比P幀小,也是在場景轉(zhuǎn)換的時候,B幀有可能跟前后某幀差別很大,無法參考數(shù)據(jù),于是數(shù)據(jù)量很大。
  • 所以說,每類幀類型的使用位置還是很重要的,每一幀給合適的幀類型,才能發(fā)揮好壓縮效果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容