一、為什么要進(jìn)行視頻編碼
未經(jīng)壓縮的視頻的數(shù)據(jù)量巨大,錄制一分鐘視頻, 需要多大的空間來保存了?
1> 為了不讓用戶感受到卡頓效果, 1秒鐘之內(nèi)至少需要16幀畫面(正常開發(fā)通常會(huì)采集30幀),也就是編碼設(shè)置的fps參數(shù)
2> 假如該視頻是一個(gè)1280*720分辨率的視頻(正常情況下會(huì)比這個(gè)大很多)
結(jié)果:128072016*60≈843.75M
一分鐘的視頻843M,如果保證播放不卡頓,則需要15M/S 的下載速度,如果使用蜂窩網(wǎng)絡(luò)...
結(jié)論:1.如此大的傳輸數(shù)據(jù)量,現(xiàn)行帶寬壓力巨大,流量資費(fèi)大,且存儲(chǔ)數(shù)據(jù)量也極大,所以導(dǎo)致編碼技術(shù)的產(chǎn)生
?????????? 2.視頻采集完成后,需要先編碼,再傳輸,在解碼,再播放(重現(xiàn))
二、為什么視頻可以壓縮編碼?
采集到的視頻源存在冗余信息,冗余信息分為以下三類:
1.空間冗余:圖像相鄰像素之間有較強(qiáng)的相關(guān)性
2.時(shí)間冗余:視頻序列的相鄰圖像之間內(nèi)容相似
3.視覺冗余:人的視覺系統(tǒng)對(duì)某些細(xì)節(jié)不敏感
4.其他冗余
空間冗余
空間冗余是指在同一張圖像中,有很多像素點(diǎn)表示的信息是完全一樣的,如果對(duì)每一個(gè)像素進(jìn)行單獨(dú)的存儲(chǔ),必然會(huì)非常浪費(fèi)空間,也完全沒有必要,此處部分存儲(chǔ)的顏色色值相同,僅僅對(duì)應(yīng)空間位置不同。

時(shí)間冗余
時(shí)間冗余是指多張圖像之間,有非常多的相關(guān)性,由于一些小運(yùn)動(dòng)造成了細(xì)小差別。
我們可以看到兩張圖片相隔很近,彼此之間很多元素相同,如果對(duì)相同部分多次存儲(chǔ),則形成了冗余
如圖:

視覺冗余
1.人類視覺系統(tǒng)HVS
2.對(duì)高頻信息不敏感
3.對(duì)高對(duì)比度更敏感
4.對(duì)亮度信息比色度信息更敏感
5.對(duì)運(yùn)動(dòng)的信息更敏感
數(shù)字視頻系統(tǒng)的設(shè)計(jì)應(yīng)該考慮HVS的特點(diǎn):
1.丟棄高頻信息,只編碼低頻信息
2.提高邊緣信息的主觀質(zhì)量
3.降低色度的解析度
對(duì)感興趣區(qū)域(Region of Interesting,ROI)進(jìn)行特殊處理
如圖:

經(jīng)過一系列的去處冗余信息,可以大大的降低視頻的數(shù)據(jù)量,更利于視頻的保存、傳輸,去除冗余信息的過程,我們就稱之為壓縮編碼
三、壓縮編碼的標(biāo)準(zhǔn)
1.? 標(biāo)準(zhǔn)化組織:
ITU:International Telecommunications Union
VECG:Video Coding Experts Group(國(guó)際電傳視訊聯(lián)盟)
ISO:International Standards Organization
MPEG:Motion Picture Experts Group(國(guó)際標(biāo)準(zhǔn)組織機(jī)構(gòu))
2.?? H.26X系列(由ITU[國(guó)際電傳視訊聯(lián)盟]主導(dǎo))
H.261:主要在老的視頻會(huì)議和視頻電話產(chǎn)品中使用
H.263:主要用在視頻會(huì)議、視頻電話和網(wǎng)絡(luò)視頻上
H.264:H.264/MPEG-4第十部分,或稱AVC(Advanced Video Coding,高級(jí)視頻編碼),是一種視頻壓縮標(biāo)準(zhǔn),一種被廣泛使用的高精度視頻的錄制、壓縮和發(fā)布格式。
H.265:高效率視頻編碼(High Efficiency Video
Coding,簡(jiǎn)稱HEVC)是一種視頻壓縮標(biāo)準(zhǔn),H.264/MPEG-4
AVC的繼任者??芍С?K分辨率甚至到超高畫質(zhì)電視,最高分辨率可達(dá)到8192×4320(8K分辨率),這是目前發(fā)展的趨勢(shì),尚未有大眾化編碼軟件出現(xiàn)
3.MPEG系列(由ISO[國(guó)際標(biāo)準(zhǔn)組織機(jī)構(gòu)]下屬的MPEG[運(yùn)動(dòng)圖象專家組]開發(fā))
MPEG-1第二部分:MPEG-1第二部分主要使用在VCD上,有些在線視頻也使用這種格式
MPEG-2第二部分(MPEG-2第二部分等同于H.262,使用在DVD、SVCD和大多數(shù)數(shù)字視頻廣播系統(tǒng)中
MPEG-4第二部分(MPEG-4第二部分標(biāo)準(zhǔn)可以使用在網(wǎng)絡(luò)傳輸、廣播和媒體存儲(chǔ)上)。
其他系列:
AMV · AVS · Bink · RealVideo · Theora · VC-1 · VP3 · VP6 · VP7 · VP8 · VP9 · WMV
四、目前應(yīng)用最廣泛的H.264(AVC)
H264是新一代的編碼標(biāo)準(zhǔn),以高壓縮高質(zhì)量和支持多種網(wǎng)絡(luò)的流媒體傳輸著稱
個(gè)人理解:
在相鄰幾幅圖像畫面中,一般有差別的像素只有10%以內(nèi)的點(diǎn),亮度差值變化不超過2%,而色度差值的變化只有1%以內(nèi),所以對(duì)于一段變化不大圖像畫面,我們可以先編碼出一個(gè)完整的圖像幀A,隨后的B幀就不編碼全部圖像,只寫入與A幀的差別,這樣B幀的大小就只有完整幀的1/10或更??!B幀之后的C幀如果變化不大,我們可以繼續(xù)以參考B的方式編碼C幀,這樣循環(huán)下去。這段圖像我們稱為一個(gè)序列:序列就是有相同特點(diǎn)的一段數(shù)據(jù),當(dāng)某個(gè)圖像與之前的圖像變化很大,無法參考前面的幀來生成,那我們就結(jié)束上一個(gè)序列,開始下一段序列,也就是對(duì)這個(gè)圖像生成一個(gè)完整幀A1,隨后的圖像就參考A1生成,只寫入與A1的差別內(nèi)容。
在H264協(xié)議里定義了三種幀
I幀:完整編碼的幀叫I幀
P幀:參考之前的I幀生成的只包含差異部分編碼的幀叫P幀
B幀:參考前后的幀編碼的幀叫B幀
H264采用的核心算法是幀內(nèi)壓縮和幀間壓縮
幀內(nèi)壓縮是生成I幀的算法
幀間壓縮是生成B幀和P幀的算法
H264的壓縮方法:
分組:把幾幀圖像分為一組(GOP,也就是一個(gè)序列),為防止運(yùn)動(dòng)變化,幀數(shù)不宜取多
定義幀:將每組內(nèi)各幀圖像定義為三種類型,即I幀、B幀和P幀;
預(yù)測(cè)幀:以I幀做為基礎(chǔ)幀,以I幀預(yù)測(cè)P幀,再由I幀和P幀預(yù)測(cè)B幀;
數(shù)據(jù)傳輸:最后將I幀數(shù)據(jù)與預(yù)測(cè)的差值信息進(jìn)行存儲(chǔ)和傳輸。
序列(GOP)
在H264中圖像以序列為單位進(jìn)行組織,一個(gè)序列是一段圖像編碼后的數(shù)據(jù)流。
一個(gè)序列的第一個(gè)圖像叫做 IDR 圖像(立即刷新圖像),IDR 圖像都是 I 幀圖像。
H.264 引入 IDR 圖像是為了解碼的重同步,當(dāng)解碼器解碼到 IDR 圖像時(shí),立即將參考幀隊(duì)列清空,將已解碼的數(shù)據(jù)全部輸出或拋棄,重新查找參數(shù)集,開始一個(gè)新的序列。
這樣,如果前一個(gè)序列出現(xiàn)重大錯(cuò)誤,在這里可以獲得重新同步的機(jī)會(huì)。
IDR圖像之后的圖像永遠(yuǎn)不會(huì)使用IDR之前的圖像的數(shù)據(jù)來解碼,這樣可以避免前一個(gè)IDR圖像錯(cuò)誤而導(dǎo)致整個(gè)視頻無法播放。
一個(gè)序列就是一段內(nèi)容差異不太大的圖像編碼后生成的一串?dāng)?shù)據(jù)流
當(dāng)運(yùn)動(dòng)變化比較少時(shí),一個(gè)序列可以很長(zhǎng),因?yàn)檫\(yùn)動(dòng)變化少就代表圖像畫面的內(nèi)容變動(dòng)很小,所以就可以編一個(gè)I幀,然后一直P幀、B幀了。
當(dāng)運(yùn)動(dòng)變化多時(shí),可能一個(gè)序列就比較短了,比如就包含一個(gè)I幀和3、4個(gè)P幀。
在視頻編碼序列中,GOP即Group of picture(圖像組),指兩個(gè)I幀之間的距離
I幀、P幀、B幀的預(yù)測(cè)方向

I幀、P幀、B幀實(shí)際順序&編碼后順序

五、H264分層設(shè)計(jì)
分層設(shè)計(jì)
H264算法在概念上分為兩層:
1.視頻編碼層(VCL:Video Coding Layer)負(fù)責(zé)高效的視頻內(nèi)容表示,
2.網(wǎng)絡(luò)提取層(NAL:Network Abstraction Layer)負(fù)責(zé)以網(wǎng)絡(luò)所要求的恰當(dāng)?shù)姆绞綄?duì)數(shù)據(jù)進(jìn)行打包和傳送
這樣,高效編碼和網(wǎng)絡(luò)友好性分別由VCL和NAL分別完成,而之前我們學(xué)習(xí)的編碼方式,都是屬于VCL層,VCL層可看做H264編碼算法中去除冗余數(shù)據(jù)的過程,更詳細(xì)的介紹請(qǐng)參考鏈接
NAL設(shè)計(jì)目的:
根據(jù)不同的網(wǎng)絡(luò)把數(shù)據(jù)打包成相應(yīng)的格式,將VCL產(chǎn)生的比特字符串適配到各種各樣的網(wǎng)絡(luò)和多元環(huán)境中。
NAL的封裝方式:
NAL是將每一幀數(shù)據(jù)寫入到一個(gè)NAL單元中,進(jìn)行傳輸或存儲(chǔ)的
NALU分為NAL頭和NAL體
NALU頭通常為00 00 00 01,作為一個(gè)新的NALU的起始標(biāo)識(shí)
NALU體封裝著VCL編碼后的信息或者其他信息
封裝過程:
I幀、P幀、B幀都是被封裝成一個(gè)或者多個(gè)NALU進(jìn)行傳輸或者存儲(chǔ)的
I幀開始之前也有非VCL的NAL單元,用于保存其他信息,比如:PPS、SPS
PPS(Picture Parameter Sets):圖像參數(shù)集
SPS(Sequence Parameter Set):序列參數(shù)集
在實(shí)際的H264數(shù)據(jù)幀中,往往幀前面帶有00 00 00 01 或 00 00 01分隔符,一般來說編碼器編出的首幀數(shù)據(jù)為PPS與SPS,接著為I幀,后續(xù)是B幀、P幀等數(shù)據(jù)

六、編碼方式
編碼的方式有兩種:
硬編碼:使用非CPU進(jìn)行編碼,如顯卡GPU、專用的DSP、FPGA、ASIC芯片等
軟編碼:使用CPU進(jìn)行編碼,軟編碼通常使用:ffmpeg+x264
ffmpeg:是一套開源的、用于對(duì)音視頻進(jìn)行編碼&解碼&轉(zhuǎn)化計(jì)算機(jī)程序
x264:x264是一種免費(fèi)的、開源的、具有更優(yōu)秀算法的H.264/MPEG-4 AVC視頻壓縮編碼方式
對(duì)比:
軟編碼:實(shí)現(xiàn)直接、簡(jiǎn)單,參數(shù)調(diào)整方便,升級(jí)易,但CPU負(fù)載重,性能較硬編碼低
硬編碼:性能高,對(duì)CPU沒有壓力,但是對(duì)其他硬件要求較高(如GPU等)
iOS中編碼方式:
在iOS8之前,蘋果并沒有開放硬編碼的接口,所以只能采用ffpeng+x624進(jìn)行軟編碼
在iOS8之后,蘋果開放了接口,并且封裝了VideoToolBox&AudioToolbox兩個(gè)框架,分別用于對(duì)視頻&音頻進(jìn)行硬編碼