視頻編碼與解碼

井底燕雀儻
井底燕雀儻 2023-04-22 14:53
H264視頻壓縮算法目前無(wú)疑是所有視頻壓縮技術(shù)中使用最廣泛,最流行的,如今很多開源庫(kù)基于H264提供了編解碼接口。
但為了用好H264,我們或是要對(duì)H264的基本原理弄清楚才行。今天我們就來看看H264的基本原理。
H264概述




H264壓縮技術(shù)主要采用了以下幾種方法對(duì)視頻數(shù)據(jù)進(jìn)行壓縮。包括:

  • 幀內(nèi)預(yù)測(cè)壓縮,解決的是空域數(shù)據(jù)冗余問題。
  • 幀間預(yù)測(cè)壓縮(運(yùn)動(dòng)估計(jì)與補(bǔ)償),解決的是時(shí)域數(shù)據(jù)冗徐問題。  
  • 整數(shù)離散余弦變換(DCT),將空間上的相關(guān)性變?yōu)轭l域上無(wú)關(guān)的數(shù)據(jù)然后進(jìn)行量化。  
  • CABAC壓縮。
經(jīng)過壓縮后的幀分為:I幀,P幀和B幀:

  • I幀:關(guān)鍵幀,采用幀內(nèi)壓縮技術(shù)?! ?br />
  • P幀:向前參考幀,在壓縮時(shí),只參考前面已經(jīng)處理的幀。采用幀音壓縮技術(shù)。  
  • B幀:雙向參考幀,在壓縮時(shí),它即參考前而的幀,又參考它后面的幀。采用幀間壓縮技術(shù)。
除了I/P/B幀外,還有圖像序列GOP。
GOP:兩個(gè)I幀之間是一臺(tái)圖像序列,在一臺(tái)圖像序列中只有一臺(tái)I幀。如下圖所示:


下面我們就來詳細(xì)描述一下H264壓縮技術(shù)。
H264壓縮技術(shù)

H264的基本原理其實(shí)非常簡(jiǎn)單,下我們就簡(jiǎn)單的描述一下H264壓縮數(shù)據(jù)的過程。通過攝像頭采集到的視頻幀(按每秒 30 幀算),被送到 H264 編碼器的緩沖區(qū)中。編碼器先要為每一幅圖片劃分宏塊。
以下面這張圖為例:


劃分宏塊

H264默認(rèn)是使用 16X16 大小的區(qū)域作為一臺(tái)宏塊,也可以劃分成 8X8 大小。


劃分好宏塊后,計(jì)算宏塊的象素值。


以此類推,計(jì)算一幅圖像中每個(gè)宏塊的像素值,所有宏塊都處理完后如下面的樣子。


劃分子塊

H264對(duì)比較平坦的圖像使用 16X16 大小的宏塊。但為了更高的壓縮率,還可以在 16X16 的宏塊上更劃分出更小的子塊。子塊的大小可以是 8X16? 16X8? 8X8? 4X8? 8X4? 4X4非常的靈活。


上幅圖中,紅框內(nèi)的 16X16 宏塊中大部分是藍(lán)色背景,而三只鷹的部分圖像被劃在了該宏塊內(nèi),為了更好的處理三只鷹的部分圖像,H264就在 16X16 的宏塊內(nèi)又劃分出了多個(gè)子塊。


這樣再經(jīng)過幀內(nèi)壓縮,可以得到更高效的數(shù)據(jù)。下圖是分別使用mpeg-2和H264對(duì)上面宏塊進(jìn)行壓縮后的結(jié)果。其中左半部分為MPEG-2子塊劃分后壓縮的結(jié)果,右半部分為H264的子塊劃壓縮后的結(jié)果,可以看出H264的劃分方法更具優(yōu)勢(shì)。


宏塊劃分好后,就可以對(duì)H264編碼器緩存中的所有圖片進(jìn)行分組了。
幀分組

對(duì)于視頻數(shù)據(jù)主要有兩類數(shù)據(jù)冗余,一類是時(shí)間上的數(shù)據(jù)冗余,另一類是空間上的數(shù)據(jù)冗余。其中時(shí)間上的數(shù)據(jù)冗余是最大的。下面我們就先來說說視頻數(shù)據(jù)時(shí)間上的冗余問題。
為啥說時(shí)間上的冗余是最大的呢?假設(shè)攝像頭每秒抓取30幀,這30幀的數(shù)據(jù)大部分情況下都是相關(guān)聯(lián)的。也有可能不止30幀的的數(shù)據(jù),可能幾十幀,上百幀的數(shù)據(jù)都是關(guān)聯(lián)特別密切的。
對(duì)于這些關(guān)聯(lián)特別密切的幀,其實(shí)我們只需要保存一幀的數(shù)據(jù),其它幀都可以通過這一幀再按某種規(guī)則預(yù)測(cè)出來,所以說視頻數(shù)據(jù)在時(shí)間上的冗余是最多的。
為了達(dá)到相關(guān)幀通過預(yù)測(cè)的方法來壓縮數(shù)據(jù),就需要將視頻幀進(jìn)行分組。那么如何判定某些幀關(guān)系密切,可以劃為一組呢?我們來看一下例子,下面是捕獲的一組運(yùn)動(dòng)的臺(tái)球的視頻幀,臺(tái)球從右上角滾到了左下角。




H264編碼器會(huì)按順序,每次取出兩幅相鄰的幀進(jìn)行宏塊比較,計(jì)算兩幀的相似度。如下圖:


通過宏塊掃描與宏塊搜索可以發(fā)現(xiàn)這兩個(gè)幀的關(guān)聯(lián)度是非常高的。進(jìn)而發(fā)現(xiàn)這一組幀的關(guān)聯(lián)度都是非常高的。因此,上面這幾幀就可以劃分為一組。其算法是:在相鄰幾幅圖像畫面中,一般有差別的像素只有10%以內(nèi)的點(diǎn),亮度差值變化不超過2%,而色度差值的變化只有1%以內(nèi),我們認(rèn)為這樣的圖可以分到一組。
在這樣一組幀中,經(jīng)過編碼后,我們只保留第一帖的完整數(shù)據(jù),其它幀都通過參考上一幀計(jì)算出來。我們稱第一幀為IDR/I幀,其它幀我們稱為P/B幀,這樣編碼后的數(shù)據(jù)幀組我們稱為GOP
運(yùn)動(dòng)估計(jì)與補(bǔ)償

在H264編碼器中將幀分組后,就要計(jì)算幀組內(nèi)物體的運(yùn)動(dòng)矢量了。還以上面運(yùn)動(dòng)的臺(tái)球視頻幀為例,我們來看一下它是如何計(jì)算運(yùn)動(dòng)矢量的。
H264編碼器首先按順序從緩沖區(qū)頭部取出兩幀視頻數(shù)據(jù),然后進(jìn)行宏塊掃描。當(dāng)發(fā)現(xiàn)其中一幅圖片中有物體時(shí),就在另一幅圖的鄰近位置(搜索窗口中)進(jìn)行搜索。如果此時(shí)在另一幅圖中找到該物體,那么就可以計(jì)算出物體的運(yùn)動(dòng)矢量了。下面這幅圖就是搜索后的臺(tái)球移動(dòng)的位置。


通過上圖中臺(tái)球位置相差,就可以計(jì)算出臺(tái)圖運(yùn)行的方向和距離。H264依次把每一幀中球移動(dòng)的距離和方向都記錄下來就成了下面的樣子。


運(yùn)動(dòng)矢量計(jì)算出來后,將相同部分(也就是綠色部分)減去,就得到了補(bǔ)償數(shù)據(jù)。我們最終只需要將補(bǔ)償數(shù)據(jù)進(jìn)行壓縮保存,以后在解碼時(shí)就可以恢復(fù)原圖了。壓縮補(bǔ)償后的數(shù)據(jù)只需要記錄很少的一點(diǎn)數(shù)據(jù)。如下所示:


我們把運(yùn)動(dòng)矢量與補(bǔ)償稱為幀間壓縮技術(shù),它解決的是視頻幀在時(shí)間上的數(shù)據(jù)冗余。除了幀間壓縮,幀內(nèi)也要進(jìn)行數(shù)據(jù)壓縮,幀內(nèi)數(shù)據(jù)壓縮解決的是空間上的數(shù)據(jù)冗余。下面我們就來介紹一下幀內(nèi)壓縮技術(shù)。
幀內(nèi)預(yù)測(cè)

人眼對(duì)圖象都有一臺(tái)識(shí)別度,對(duì)低頻的亮度很敏感,對(duì)高頻的亮度不太敏感。所以基于一些研究,可以將一幅圖像中人眼不敏感的數(shù)據(jù)去除掉。這樣就提出了幀內(nèi)預(yù)測(cè)技術(shù)。
H264的幀內(nèi)壓縮與JPEG很相似。一幅圖像被劃分好宏塊后,對(duì)每個(gè)宏塊可以進(jìn)行 9 種模式的預(yù)測(cè)。找出與原圖最接近的一種預(yù)測(cè)模式。


下面這幅圖是對(duì)整幅圖中的每個(gè)宏塊進(jìn)行預(yù)測(cè)的過程。


幀內(nèi)預(yù)測(cè)后的圖像與原始圖像的對(duì)比如下:


然后,將原始圖像與幀內(nèi)預(yù)測(cè)后的圖像相減得殘差值。


再將我們之前得到的預(yù)測(cè)模式信息一起保存起來,這樣我們就可以在解碼時(shí)恢復(fù)原圖了。效果如下:


經(jīng)過幀內(nèi)與幀間的壓縮后,雖然數(shù)據(jù)有大幅減少,但還有優(yōu)化的空間。
對(duì)殘差數(shù)據(jù)做DCT

可以將殘差數(shù)據(jù)做整數(shù)離散余弦變換,去掉數(shù)據(jù)的相關(guān)性,進(jìn)一步壓縮數(shù)據(jù)。如下圖所示,左側(cè)為原數(shù)據(jù)的宏塊,右側(cè)為計(jì)算出的殘差數(shù)據(jù)的宏塊。


將殘差數(shù)據(jù)宏塊數(shù)字化后如下圖所示:


將殘差數(shù)據(jù)宏塊進(jìn)行 DCT 轉(zhuǎn)換。


去掉相關(guān)聯(lián)的數(shù)據(jù)后,我們可以看出數(shù)據(jù)被進(jìn)一步壓縮了。


做完 DCT 后,還不夠,還要進(jìn)行 CABAC 進(jìn)行無(wú)損壓縮。
DCT原理大白話

這是第一幀畫面:P1(我們的參考幀)


這是第二幀畫面:P2(需要編碼的幀)



從視頻中截取的兩張間隔1-2秒的畫面,和實(shí)際情況類似,下面我們進(jìn)行幾次運(yùn)動(dòng)搜索:
這是一臺(tái)演示程序,鼠標(biāo)選中P2上任意16x16的Block,即可搜索出P1上的 BestMatch 宏塊。雖然車輛在運(yùn)動(dòng),從遠(yuǎn)到近,但是依然找到了最接近的宏塊坐標(biāo)。


這是一臺(tái)演示程序,鼠標(biāo)選中P2上任意16x16的Block,即可搜索出P1上的 BestMatch 宏塊。雖然車輛在運(yùn)動(dòng),從遠(yuǎn)到近,但是依然找到了最接近的宏塊坐標(biāo)。
搜索演示2:空中電線交叉位置(上圖P1,下圖P2)


搜索演示3:報(bào)刊停的廣告海報(bào)


同樣順利在P1中找到最接近P2里海報(bào)的宏塊位置。
圖片全搜索:根據(jù)P1和運(yùn)動(dòng)矢量數(shù)據(jù)(在P2中搜索到每一臺(tái)宏塊在P1中最相似的位置集合)還原出來的P2',即完全用P1各個(gè)位置的宏塊拼湊出來最像P2的圖片P2',效果如下:



仔細(xì)觀察,有些支離破碎對(duì)吧?肯定啊,拼湊出來的東西就是這樣,目前我們用P2`和P2像素相減,得到差分圖 D2 = (P2' - P2) / 2 + 0x80:





這就是之前支離破碎的 P2` 加上誤差 D2之后變成了清晰可見的樣子,基本還原了原圖P2。


由于D2僅僅占5KB,加上壓縮過后的運(yùn)動(dòng)矢量不過7KB,所以參考P1我們只需要額外 7KB的數(shù)據(jù)量就可以完整表示P2了,而如果獨(dú)立將P2用質(zhì)量尚可的有損壓縮方式獨(dú)立壓縮,則至少要去到50-60KB,這一下節(jié)省了差不多8倍的空間,正就是所謂運(yùn)動(dòng)編碼的基本原理。

實(shí)際在使用中,參考幀并不一定是前面一幀,也不一定是同一臺(tái)GOP的I幀,因?yàn)镚OP間隔較長(zhǎng)時(shí),后面的圖片離I幀變化可能已經(jīng)很大了,因此常見做法是最近15幀中選擇一幀誤差最小的作為參考幀,雖然彩色畫面有YUV三個(gè)分量,但是大量的預(yù)測(cè)工作和最有選擇通常是根據(jù)Y分量的灰度幀進(jìn)行判斷的。
再者誤差我們保存的是(P2-P2’)/2 + 0x80,實(shí)際使用時(shí)我們會(huì)用更有效率的方式,比如讓[-64,64]之間的色差精度為1,[-255,-64], [64, 255] 之間的色差精度為2-3,這樣會(huì)更加真實(shí)一些。
同時(shí)上文很多地方用的是直接lzma2進(jìn)行簡(jiǎn)單存儲(chǔ),實(shí)際使用時(shí)一般會(huì)引入熵編碼,對(duì)數(shù)據(jù)進(jìn)行一定層次的整理然后再壓縮,性能會(huì)好不少。
CABAC

上面的幀內(nèi)壓縮是屬于有損壓縮技術(shù)。也就是說圖像被壓縮后,無(wú)法完全復(fù)原。而CABAC屬于無(wú)損壓縮技術(shù)。
無(wú)損壓縮技術(shù)大家最熟悉的可能就是哈夫曼編碼了,給高頻的詞一臺(tái)短碼,給低頻詞一臺(tái)長(zhǎng)碼從而達(dá)到數(shù)據(jù)壓縮的目的。MPEG-2中使用的VLC就是這種算法,我們以 A-Z 作為例子,A屬于高頻數(shù)據(jù),Z屬于低頻數(shù)據(jù)??纯此侨绾巫龅?。


CABAC也是給高頻數(shù)據(jù)短碼,給低頻數(shù)據(jù)長(zhǎng)碼。同時(shí)還會(huì)根據(jù)上下文相關(guān)性進(jìn)行壓縮,這種方式又比VLC高效很多。其效果如下:


目前將 A-Z 換成視頻幀,它就成了下面的樣子。


從上面這張圖中明顯可以看出采用 CACBA 的無(wú)損壓縮方案要比 VLC 高效的多。

本文簡(jiǎn)要分析了H264的基本原理,如有不足之處,歡迎指正,只為共同進(jìn)步,在這波內(nèi)卷的浪潮中,希望你我都能走好運(yùn)、賺大錢、泡洋妞。
相關(guān)標(biāo)簽:
9條回答
  • 2023-04-22 15:32
    看了眼日期,竟然不是發(fā)布于2010年
    0 討論(0)
  • 整篇文章有種“易證得”的感覺
    0 討論(0)
  • 2023-04-22 15:43
    專業(yè)
    0 討論(0)
提交回復(fù)
最新問題
小度智能屏應(yīng)用中心都有哪些應(yīng)用 1
去哪家專治輸卵管堵了醫(yī)院好 1
人工智能專業(yè)學(xué)校排名 1
咸陽(yáng)不育怎么治療 1
小度智能屏Ⅹ8酒店版拿回家如何解鎖 1
小度智能屏費(fèi)電嗎 1
72NTSC比99%sRGB顏色好看如何回事? 1
輸卵管堵塞粘連如何治療好 1
容聲冰箱觸摸屏溫度調(diào)節(jié)圖解是指什么? 1
明基MX703 網(wǎng)絡(luò)控制 有什么用? 2
猜你喜歡
三代試管養(yǎng)囊成功比例大嗎?能保證成功嗎?
福建省醫(yī)院三代試管多少錢!要看實(shí)際情況!
試管嬰兒是否必須做兩癌篩查,要不要做還要看情況
2025煙臺(tái)公立醫(yī)院三代試管嬰兒費(fèi)用,全部費(fèi)用明細(xì)!
在青島市試管助孕醫(yī)院做三代試管花費(fèi)7.5w三代試管流程和費(fèi)用!怎樣保證安全!
濰坊做三代試管最權(quán)威的醫(yī)院地址!
山西做三代試管最權(quán)威的醫(yī)院有哪家?
重慶試管嬰兒費(fèi)用透明指南?3-5萬(wàn)足夠了!
2025年佛山地區(qū)試管嬰兒費(fèi)用詳解及行業(yè)收費(fèi)參考!越吃血壓越低!
烏魯木齊做三代試管嬰兒的醫(yī)院是哪三家?烏魯木齊正規(guī)試管機(jī)構(gòu)排名
熱門文章
蘭州第三代試管私立醫(yī)院預(yù)約流程
“探討”子宮內(nèi)膜厚能做試管嗎?多少錢?
拉拉les做試管嬰兒費(fèi)用標(biāo)準(zhǔn)
泰國(guó)試管不需要結(jié)婚證的醫(yī)院排名發(fā)布
泰國(guó)比較大的助孕公司哪個(gè)比較好?
去海外做三代試管怎么選私立醫(yī)院?附2025靠譜醫(yī)院名單
泰國(guó)私立試管醫(yī)院名單盤點(diǎn),一分鐘介紹靠譜醫(yī)院
2025年泰國(guó)試管嬰兒醫(yī)院評(píng)選:十大名單公布
深圳私立醫(yī)院做三代試管怎么樣?本地人都推薦這幾家
做泰國(guó)試管嬰兒醫(yī)院選擇,公立和私立該怎么選?
吉林私立醫(yī)院做三代試管大概需要多少費(fèi)用(能**嗎)
烏魯木齊哪可以做試管 烏魯木齊哪可以做試管嬰兒的
上海做試管嬰兒比較好的醫(yī)院大全,2024年試管嬰兒醫(yī)院排行榜
當(dāng)月聚焦!上海10大助孕機(jī)構(gòu)是哪家,人授成功率高嗎
呂梁雙胎試管嬰兒的哪個(gè)費(fèi)用更高
去泰國(guó)nic做三代試管嬰兒醫(yī)院貴不貴?費(fèi)用與效果對(duì)比
河南三代試管機(jī)構(gòu)哪里比較好(附最新醫(yī)院排名)
孕期感染了梅毒別緊張,及時(shí)采取這3步措施也能保下孩子
復(fù)旦中山醫(yī)院董曦醫(yī)生簡(jiǎn)介,擅長(zhǎng)的不止試管嬰兒促排卵
第三代泰國(guó)試管混血費(fèi)用
33歲卵巢早衰可以在玉林試管生孩子嗎附操作流程及飲食禁忌
美國(guó)試管嬰兒手術(shù)費(fèi)用是多少?三代試管嬰兒費(fèi)用構(gòu)成解析
泰國(guó)三代試管成功率是多少?怎么提高成功率?
南京可開展試管技術(shù)的私人機(jī)構(gòu)有哪些?挑選美國(guó)頂級(jí)試管嬰兒中心至關(guān)重要
泰國(guó)試管的成功率是多少?成功率有多高?
廣告合作方 廣告申請(qǐng)