Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 499, comments - 13, trackbacks - 0, articles - 1

          本文引用了“拍樂云Pano”的“深入淺出理解視頻編解碼技術(shù)”和“揭秘視頻千倍壓縮背后的技術(shù)原理之預(yù)測技術(shù)”文章部分內(nèi)容,感謝原作者的分享。

          1、引言

          從 20 世紀(jì) 90 年代以來,數(shù)字音視頻編解碼技術(shù)迅速發(fā)展,一直是國內(nèi)外研究的熱點領(lǐng)域。隨著5G的成熟和廣泛商用,帶寬已經(jīng)越來越高,傳輸音視頻變得更加容易。視頻直播、視頻聊天,已經(jīng)完全融入了每個人的生活。

          視頻為何如此普及呢?是因為通過視頻能方便快捷地獲取到大量信息。但視頻數(shù)據(jù)量非常巨大,視頻的網(wǎng)絡(luò)傳輸也面臨著巨大的挑戰(zhàn)。于是視頻編解碼技術(shù)就出場了。

          具體到實時視頻場景,不僅僅是數(shù)據(jù)量的問題,實時通信對時延要求、設(shè)備適配、帶寬適應(yīng)的要求也非常高,要解決這些問題,始終離不開視頻編解碼技術(shù)的范疇。

          本文將從視頻編解碼技術(shù)的基礎(chǔ)知識入手,引出視頻編解碼技術(shù)中非常基礎(chǔ)且重要的預(yù)測技術(shù),學(xué)習(xí)幀內(nèi)預(yù)測和幀間預(yù)測的技術(shù)原理。

          本文已同步發(fā)布于:http://www.52im.net/thread-3581-1-1.html

          2、相關(guān)文章

          如果你是音視頻技術(shù)初學(xué)者,以下3篇入門級干貨非常推薦一讀:

          零基礎(chǔ),史上最通俗視頻編碼技術(shù)入門

          零基礎(chǔ)入門:實時音視頻技術(shù)基礎(chǔ)知識全面盤點

          實時音視頻面視必備:快速掌握11個視頻技術(shù)相關(guān)的基礎(chǔ)概念

          3、為什么需要視頻編解碼

          首先,來復(fù)習(xí)一下視頻編解碼方面的理論常識。

          視頻是由一系列圖片按照時間順序排列而成:

          • 1)每一張圖片為一幀;
          • 2)每一幀可以理解為一個二維矩陣;
          • 3)矩陣的每個元素為一個像素。

          一個像素通常由三個顏色進行表達,例如用RGB顏色空間表示時,每一個像素由三個顏色分量組成。每一個顏色分量用1個字節(jié)來表達,其取值范圍就是0~255。編碼中常用的YUV格式與之類似,這里不作展開。

          1280x720@60fps的視頻序列為例,十秒鐘的視頻有:1280*720*3*60*10 = 1.6GB

          如此大量的數(shù)據(jù),無論是存儲還是傳輸,都面臨巨大的挑戰(zhàn)。視頻壓縮或者編碼的目的,也是為了保證視頻質(zhì)量的前提下,將視頻減小,以利于傳輸和存儲。同時,為了能正確還原視頻,需要將其解碼。

          PS:限于篇幅,視頻編解碼方面的技術(shù)原理就不在此展開,有興趣強烈推薦從這篇深入學(xué)習(xí):即時通訊音視頻開發(fā)(十九):零基礎(chǔ),史上最通俗視頻編碼技術(shù)入門》。

          總之,視頻編解碼技術(shù)的主要作用就是:在可用的計算資源內(nèi),追求盡可能高的視頻重建質(zhì)量和盡可能高的壓縮比,以達到帶寬和存儲容量的要求。

          為何突出“重建質(zhì)量”?

          因為視頻編碼是個有損的過程,用戶只能從收到的視頻流中解析出“重建”畫面,它與原始的畫面已經(jīng)不同,例如觀看低質(zhì)量視頻時經(jīng)常會碰到的“塊”效應(yīng)。

          如何在一定的帶寬占用下,盡可能地保持視頻的質(zhì)量,或者在保持質(zhì)量情況下,盡可能地減少帶寬利用率,是視頻編碼的基本目標(biāo)。

          用專業(yè)術(shù)語來說,即視頻編解碼標(biāo)準(zhǔn)的“率失真”性能:

          • 1)“率”是指碼率或者帶寬占用;
          • 2)“失真”是用來描述重建視頻的質(zhì)量。

          與編碼相對應(yīng)的是解碼或者解壓縮過程,是將接收到的或者已經(jīng)存儲在介質(zhì)上的壓縮碼流重建成視頻信號,然后在各種設(shè)備上進行顯示。

          4、什么是視頻編解碼標(biāo)準(zhǔn)

          視頻編解碼標(biāo)準(zhǔn),通常只定義上述的解碼過程。

          例如 H.264 / AVC 標(biāo)準(zhǔn),它定義了什么是符合標(biāo)準(zhǔn)的視頻流,對每一個比特的順序和意義都進行了嚴(yán)格地定義,對如何使用每個比特或者幾個比特表達的信息也有精確的定義。

          正是這樣的嚴(yán)格和精確,保證了不同廠商的視頻相關(guān)服務(wù),可以很方便地兼容在一起,例如用 iPhone、Android Phone 或者 windows PC 都可以觀看同一在線視頻網(wǎng)站的同一視頻。

          世界上有多個組織進行視頻編碼標(biāo)準(zhǔn)的制定工作,國際標(biāo)準(zhǔn)組織 ISO 的 MPEG 小組、國際電信聯(lián)盟 ITU-T 的 VCEG 小組、中國的 AVS 工作組、Google 及各大廠商組成的開放媒體聯(lián)盟等。

          視頻編碼標(biāo)準(zhǔn)及發(fā)展歷史:

          自 VCEG 制定 H.120標(biāo)準(zhǔn)開始,視頻編碼技術(shù)不斷發(fā)展,先后成功地制定了一系列滿足不同應(yīng)用場景的視頻編碼標(biāo)準(zhǔn)。VCEG 組織先后制定了H.120、H.261、H.262(MPEG-2 Part 2)、H.263、H.263+、H.263++

          MPEG也先后制定了MPEG-1、MPEG-2、MPEG-4 Part 2。以及兩個國際組織合作制定的H.264/AVC、H.265/HEVC、H.266/VVC

          中國自主知識產(chǎn)權(quán)的 AVS、AVS2、AVS3 視頻編碼標(biāo)準(zhǔn);Google 制定的 VP8、VP9。

          Google、思科、微軟、蘋果等公司組成的開放媒體聯(lián)盟(AOM)制定的 AV1。

          這里特別提一下H.264/AVC:H.264/AVC雖有近20年歷史,但它優(yōu)秀的壓縮性能、適當(dāng)?shù)倪\算復(fù)雜度、優(yōu)秀的開源社區(qū)支持、友好的專利政策、強大的生態(tài)圈等多個方面的因素,依舊讓它保持著強大的生命力,特別是在實時通信領(lǐng)域。像 ZOOM、思科 Webex 等視頻會議產(chǎn)品和基于 WebRTC SDK 的視頻服務(wù),大多數(shù)主流場景都采用 H.264/AVC。

          有關(guān)視頻編解碼標(biāo)準(zhǔn),這里就不深入展開。更多詳細資料,可以讀一下下面這些精選文章:

          即時通訊音視頻開發(fā)(五):認識主流視頻編碼技術(shù)H.264

          即時通訊音視頻開發(fā)(十三):實時視頻編碼H.264的特點與優(yōu)勢

          即時通訊音視頻開發(fā)(十七):視頻編碼H.264、VP8的前世今生

          愛奇藝技術(shù)分享:輕松詼諧,講解視頻編解碼技術(shù)的過去、現(xiàn)在和將來

          5、混和編碼框架

          縱觀視頻編解碼標(biāo)準(zhǔn)歷史,每一代視頻標(biāo)準(zhǔn)都在率失真性能上有著顯著的提升,他們都有一個核心的框架,就是基于塊的混合編碼框架(如下圖所示)。它是由J. R. Jain 和A. K. Jain在1979年的國際圖像編碼學(xué)會(PCS 1979)上提出了基于塊運動補償和變換編碼的混合編碼框架。

          我們一起來對該框架進行拆解和分析。

          從攝像頭采集到的一幀視頻:通常是 YUV 格式的原始數(shù)據(jù),我們將它劃分成多個方形的像素塊依次進行處理(例如 H.264/AVC 中以16x16像素為基本單元),進行幀內(nèi)/幀間預(yù)測、正變換、量化、反量化、反變換、環(huán)路濾波、熵編碼,最后得到視頻碼流。從視頻第一幀的第一個塊開始進行空間預(yù)測,因當(dāng)前正在進行編碼處理的圖像塊和其周圍的圖像塊有相似性,我們可以用周圍的像素來預(yù)測當(dāng)前的像素。我們將原始像素減去預(yù)測像素得到預(yù)測殘差,再將預(yù)測殘差進行變換、量化,得到變換系數(shù),然后將其進行熵編碼后得到視頻碼流。

          接下來:為了可以使后續(xù)的圖像塊可以使用已經(jīng)編碼過的塊進行預(yù)測,我們還要對變換系統(tǒng)進行反量化、反變換,得到重建殘差,再與預(yù)測值進行求合,得到重建圖像。最后我們對重建圖像進行環(huán)路濾波、去除塊效應(yīng)等,這樣得到的重建圖像,就可以用來對后續(xù)圖像塊進行預(yù)測了。按照以上步驟,我們依次對后續(xù)圖像塊進行處理。

          對于視頻而言:視頻幀與幀的間隔大約只有十到幾十毫秒,通常拍攝的內(nèi)容不會發(fā)生劇烈變化,它們之間存在非常強的相關(guān)性。

          如下圖所示,將視頻圖像分割成塊,在時間相鄰的圖像之間進行匹配,然后將匹配之后的殘差部分進行編碼,這樣可以較好地去除視頻信號中的視頻幀與幀之間的冗余,達到視頻壓縮的目的。這就是運動補償技術(shù),直到今天它仍然是視頻編解碼的核心技術(shù)之一。

          運動估計和運動補償:

          變換編碼的核心思想:是把視頻數(shù)據(jù)分割成塊,利用正交變換將數(shù)據(jù)的能量集中到較少幾個變換系數(shù)上。結(jié)合量化和熵編碼,我們可以獲得更有效的壓縮。視頻編碼中信息的損失和壓縮比的獲得,很大程度上來源于量化模塊,就是將源信號中的單一樣本映射到某一固定值,形成多到少的映射,從而達到壓縮的目的,當(dāng)然在壓縮的過程中就引入了損失。量化后的信號再進行無損的熵編碼,消除信號中的統(tǒng)計冗余。熵編碼的研究最早可以追溯到 20 世紀(jì) 50 年代,經(jīng)過幾十年的發(fā)展,熵編碼在視頻編碼中的應(yīng)用更加成熟、更加精巧,充分利用視頻數(shù)據(jù)中的上下文信息,將概率模型估計得更加準(zhǔn)確,從而提高了熵編碼的效率。例如H.264/AVC中的Cavlc(基于上下文的變長編碼)、Cabac(基于上下文的二進制算術(shù)編碼)。算術(shù)編碼技術(shù)在后續(xù)的視頻編碼標(biāo)準(zhǔn),如AV1、HEVC/H.265、VVC/H.266 中也有應(yīng)用。

          視頻編碼發(fā)展至今,VVC/H.266 作為最新制定的標(biāo)準(zhǔn),采納了一系列先進的技術(shù),對混合編碼框架的各個部分都進行了優(yōu)化和改進,使得其率失真性能相比前一代標(biāo)準(zhǔn),又提高了一倍。

          例如:VVC/H.266 采用了128x128大小的基本編碼單元,并且可以繼續(xù)進行四叉樹劃分,支持對一個劃分進行二分、三分;色度分量獨立于亮度分量,支持單獨進行劃分;更多更精細的幀內(nèi)預(yù)測方向、幀間預(yù)測模式;支持多種尺寸和形式的變換、環(huán)內(nèi)濾波等。

          VVC/H.266 的制定,目標(biāo)是對多種視頻內(nèi)容有更好支持,例如屏幕共享內(nèi)容、游戲、動漫、虛擬現(xiàn)實內(nèi)容(VR、AR)等。其中也有特定的技術(shù)被采納進標(biāo)準(zhǔn),例如調(diào)色板模式、幀內(nèi)運動補償、仿射變換、跳過變換、自適應(yīng)顏色變換等。   

          回到本文的正題,接下來的內(nèi)容,我們著重介紹視頻編解碼中的預(yù)測技術(shù)。

          6、幀內(nèi)預(yù)測技術(shù)

          視頻數(shù)據(jù)被劃分成方塊之后,相鄰的方塊的像素,以及方塊內(nèi)的像素,顏色往往是逐漸變化的,他們之間有比較強的有相似性。這種相似性,就是空間冗余。既然存在冗余,就可以用更少的數(shù)據(jù)量來表達這樣的特征。

          比如:先傳輸?shù)谝粋€像素的值,再傳輸?shù)诙€像素相對于第一個像素的變化值,這個變化值往往取值范圍變小了許多,原來要8個bit來表達的像素值,可能只需要少于8個bit就足夠了。

          同樣的道理,以像素塊為基本單位,也可以進行類似的“差分”操作。我們從示例圖中,來更加直觀地感受一下這樣的相似性。

          如上圖中所標(biāo)出的兩個8x8的塊:其亮度分量(Y)沿著“左上到右下”的方向,具有連續(xù)性,變化不大。

          假如:我們設(shè)計某種特定的“模式”,使其利用左邊的塊來“預(yù)測”右邊的塊,那么“原始像素”減去“預(yù)測像素”就可以減少傳輸所需要的數(shù)據(jù)量,同時將該“模式”寫入最終的碼流,解碼器便可以利用左側(cè)的塊來“重建”右側(cè)的塊。

          極端一點講:假如左側(cè)的塊的像素值經(jīng)過一定的運算可以完全和右側(cè)的塊相同,那么編碼器只要用一個“模式”的代價,傳輸右側(cè)的塊。

          當(dāng)然,視頻中的紋理多種多樣,單一的模式很難對所有的紋理都適用,因此標(biāo)準(zhǔn)中也設(shè)計了多種多樣的幀內(nèi)預(yù)測模式,以充分利用像素間的相關(guān)性,達到壓縮的目的。

          例如下圖所示的H.264中9種幀內(nèi)預(yù)測方向:以模式0(豎直預(yù)測)為例,上方塊的每個像素值(重建)各復(fù)制一列,得到幀內(nèi)預(yù)測值。其它各種模式也采用類似的方法,不過,生成預(yù)測值的方式稍有不同。有這么多的模式,就產(chǎn)生了一個問題,對于一個塊而言,我們應(yīng)該采用哪種模式來進行編碼呢?最佳的選擇方式,就是遍歷所有的模式進行嘗試,計算其編碼的所需的比特數(shù)和產(chǎn)生的質(zhì)量損失,即率失真優(yōu)化,這樣明顯非常復(fù)雜,因而也有很多種其它的方式來推斷哪種模式更好,例如基于SATD或者邊緣檢測等。

          從H.264的9種預(yù)測模式,到AV1的56種幀內(nèi)方向預(yù)測模式,越來越多的模式也是為了更加精準(zhǔn)地預(yù)測未編碼的塊,但是模式的增加,一方面增加了傳輸模式的碼率開銷,另一方面,從如此重多的模式中選一個最優(yōu)的模式來編碼,使其能達到更高的壓縮比,這對編碼器的設(shè)計和實現(xiàn)也提出了更高的要求。

          7、幀間預(yù)測技術(shù)

          以下5張圖片是一段視頻的前5幀:可以看出,圖片中只有Mario和磚塊在運動,其余的場景大多是相似的,這種相似性就稱之為時間冗余。編碼的時候,我們先將第一幀圖片通過前文所述的幀內(nèi)預(yù)測方式進行編碼傳輸,再將后續(xù)幀的Mario、磚塊的運動方向進行傳輸,解碼的時候,就可以將運動信息和第一幀一起來合成后續(xù)的幀,這樣就大大減少了傳輸所需的bit數(shù)。這種利用時間冗余來進行壓縮的技術(shù),就是運動補償技術(shù)。該技術(shù)早在H.261標(biāo)準(zhǔn)中,就已經(jīng)被采用。

          細心地讀者可能已經(jīng)發(fā)現(xiàn):Mario和磚塊這樣的物體怎么描述,才能讓它僅憑運動信息就能完整地呈現(xiàn)出來?

          其實視頻編碼中并不需要知道運動的物體的形狀,而是將整幀圖像劃分成像素塊,每個像素塊使用一個運動信息。即基于塊的運動補償。

          下圖中紅色圈出的白色箭頭即編碼磚塊和Mario時的運動信息,它們都指向了前一幀中所在的位置。Mario和磚塊都有兩個箭頭,說明它們都被劃分在了兩個塊中,每一個塊都有單獨的運動信息。這些運動信息就是運動矢量。運動矢量有水平和豎直兩個分量,代表是的一個塊相對于其參考幀的位置變化。參考幀就是已經(jīng)編碼過的某一(多)個幀。

          當(dāng)然:傳輸運動矢量本身就要占用很多 bit。為了提高運動矢量的傳輸效率,主要有以下措施。

          一方面:可以盡可能得將塊劃分變大,共用一個運動矢量,因為平坦區(qū)域或者較大的物體,他們的運動可能是比較一致的。從 H.264 開始,可變塊大小的運動補償技術(shù)被廣泛采用。

          另一方面:相鄰的塊之間的運動往往也有比較高的相似性,其運動矢量也有較高的相似性,運動矢量本身也可以根據(jù)相鄰的塊運動矢量來進行預(yù)測,即運動矢量預(yù)測技術(shù);

          最后:運動矢量在表達物體運動的時候,有精度的取舍。像素是離散化的表達,現(xiàn)實中物體的運動顯然不是以像素為單位進行運動的,為了精確地表達物體的運動,需要選擇合適的精度來定義運動矢量。各視頻編解碼標(biāo)準(zhǔn)都定義了運動矢量的精度,運動矢量精度越高,越能精確地表達運動,但是代價就是傳輸運動矢量需要花費更多的bit。

          H.261中運動矢量是以整像素為精度的,H.264中運動矢量是以四分之一像素為精度的,AV1中還增加了八分之一精度。一般情況,時間上越近的幀,它們之間的相似性越高,也有例外,例如往復(fù)運動的場景等,可能相隔幾幀,甚至更遠的幀,會有更高的相似度。

          為了充分利用已經(jīng)編碼過的幀來提高運動補償?shù)臏?zhǔn)確度,從H.264開始引入了多參考幀技術(shù)。

          即:一個塊可以從已經(jīng)編碼過的很多個參考幀中進行運動匹配,將匹配的幀索引和運動矢量信息都進行傳輸。

          那么如何得到一個塊的運動信息呢?最樸素的想法就是,將一個塊,在其參考幀中,逐個位置進行匹配檢查,匹配度最高的,就是最終的運動矢量。

          匹配度:常用的有SAD(Sum of Absolute Difference)、SSD(Sum of Squared Difference)等。逐個位置進行匹配度檢查,即常說的全搜索運動估計,其計算復(fù)雜度可想而知是非常高的。為了加快運動估計,我們可以減少搜索的位置數(shù),類似的有很多算法,常用的如鉆石搜索、六邊形搜索、非對稱十字型多層次六邊形格點搜索算法等。

          以鉆石搜索為例,如下圖所示,以起始的藍色點為中心的9個匹配位置,分別計算這9個位置的SAD,如果SAD最小的是中心位置,下一步搜索中心點更近的周圍4個綠色點的SAD,選擇其中SAD最小的位置,繼續(xù)縮小范圍進行搜索;如果第一步中SAD最小的點不在中心,那么以該位置為中心,增加褐色的5或者3個點,繼續(xù)計算SAD,如此迭代,直到找到最佳匹配位置。

          編碼器在實現(xiàn)時,可根據(jù)實際的應(yīng)用場景,對搜索算法進行選擇。

          例如:在實時音視頻場景下,計算復(fù)雜度是相對有限的,運動估計模塊要選擇計算量較小的算法,以平衡復(fù)雜度和編碼效率。當(dāng)然,運動估計與運動補償?shù)膹?fù)雜度還與塊的大小,參考幀的個數(shù),亞像素的計算等有關(guān),在此不再深入展開。

          更多預(yù)測技術(shù)方面的原理這里就不再贅述。如果你對上面所述的預(yù)測技術(shù)理解上感到力不從心,這里有篇入門級的文章,可以先讀讀這篇《即時通訊音視頻開發(fā)(四):視頻編解碼之預(yù)測技術(shù)介紹》。

          8、寫在最后

          音視頻編解碼技術(shù),歸根結(jié)底就是在有限的資源下(網(wǎng)絡(luò)帶寬、計算資源等),讓音質(zhì)更清晰、視頻更高質(zhì)。

          這其中,對于視頻來說,質(zhì)量的提升仍然有很多可以深入研究的熱點問題。

          比如:基于人眼的主觀質(zhì)量優(yōu)化,主要利用人眼的視覺特性,將掩蔽效應(yīng)、對比度靈敏度、注意力模型等與編碼相結(jié)合,合理分配碼率、減少編碼損失引起的視覺不適。

          AI在視頻編解碼領(lǐng)域的應(yīng)用:包括將多種人工智能算法,如分類器、支持向量機、CNN等對編碼參數(shù)進行快速選擇,也可以使用深度學(xué)習(xí)對視頻進行編碼環(huán)外與編碼環(huán)內(nèi)的處理,如視頻超分辨率、去噪、去霧、自適應(yīng)動態(tài)范圍調(diào)整等編碼環(huán)外處理,達到提升視頻質(zhì)量的目的。

          此外還有打破傳統(tǒng)混合編碼框架的深度神經(jīng)網(wǎng)絡(luò)編碼,如Nvidia的Maxine視頻會議服務(wù),利用深度學(xué)習(xí)來提取特征,然后對特征進行傳輸以節(jié)省帶寬。

          附錄:更多精華文章

          [1] 實時音視頻開發(fā)的其它精華資料:

          [2] 開源實時音視頻技術(shù)WebRTC的文章:

          本文已同步發(fā)布于“即時通訊技術(shù)圈”公眾號。

          ▲ 本文在公眾號上的鏈接是:點此進入。同步發(fā)布鏈接是:http://www.52im.net/thread-3581-1-1.html



          作者:Jack Jiang (點擊作者姓名進入Github)
          出處:http://www.52im.net/space-uid-1.html
          交流:歡迎加入即時通訊開發(fā)交流群 215891622
          討論:http://www.52im.net/
          Jack Jiang同時是【原創(chuàng)Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
          本博文 歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處(也可前往 我的52im.net 找到我)。


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          Jack Jiang的 Mail: jb2011@163.com, 聯(lián)系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 且末县| 临海市| 新安县| 临夏县| 青河县| 海宁市| 三都| 梁河县| 怀集县| 苗栗市| 峨山| 毕节市| 乳山市| 太和县| 通河县| 从化市| 汨罗市| 怀安县| 江津市| 肇州县| 凤翔县| 丽江市| 巴林右旗| 屯门区| 濮阳县| 加查县| 孙吴县| 湘潭县| 新宾| 岳西县| 钟山县| 尤溪县| 石首市| 大新县| 叶城县| 天气| 文山县| 江川县| 敦煌市| 堆龙德庆县| 湖州市|