<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          神奇的H.264算法

          共 3372字,需瀏覽 7分鐘

           ·

          2022-10-25 07:05

          很開眼的一篇文章:https://sidbala.com/h-264-is-magic/

          本文是它的譯文,不會逐字翻譯,只挑有趣或重要的部分。

          H.264是視頻壓縮編解碼器標準,它的目標只有一個:減少傳輸視頻所需的寬帶。網(wǎng)絡視頻、藍光視頻、手機、無人機等等,都會使用H.264,可以說,它無處不在。

          為何需要壓縮

          視頻由幀構成,而幀其實就是圖片,而圖片其實就是一個三維矩陣(用opencv2讀取一張圖片,打印一下便知道其結構)。

          一個 60fps 的視頻,如果未壓縮,那么它每一秒的大小為:,即一個50GB的藍光光盤只能存2分鐘左右的視頻,這幾乎是不可處理的。

          所以,我們需要壓縮。

          為什么選擇H.264

          上圖是我從蘋果官網(wǎng)截圖獲得的圖片,基于這個圖片,我制作了2個文件:

          • 蘋果官網(wǎng)主頁截圖PNG文件,大小為1015KB
          • 基于同一張?zhí)O果官網(wǎng)主頁截圖,利用H.264制作的時長5秒,幀率60fps的視頻文件,大小為175KB

          沒錯,5秒的視頻文件體積更小。

          視頻每秒60fps,總共5秒,即有300幀(300個圖片矩陣),即視頻比PNG圖片多存在了300倍的數(shù)據(jù),但文件大小是PNG圖片的五分之一。

          怎么做到的?H.264會將視頻中不重要的數(shù)據(jù)全部丟掉,只留下重要的數(shù)據(jù),即H.264是一種有損數(shù)據(jù)壓縮算法,而PNG是一種無損壓縮算法。

          那H.264怎么判斷哪些數(shù)據(jù)是重要的?哪些是不重要的?嗯,這便是H.264的關鍵。

          H.264實際怎么做的

          左邊是原圖,右邊是有損壓縮后的圖片,觀察右邊圖片,蘋果筆記本的音響孔,這些孔在原圖(左邊)是清晰的,而有損壓縮后,就模糊了。這圖,經(jīng)過有損壓縮后,大小變?yōu)樵镜?%,而類似音響孔這種影響,肉眼要仔細觀察,才能看出差異。

          頻域(Frequency Domain)

          在信息論中,熵用于量化一段內(nèi)容所含的信息量。

          很多時候,內(nèi)容表現(xiàn)形式不同,但信息量卻一樣,即熵沒有變化,一個典型的例子,我們可以使用二進制來表示一段數(shù)據(jù),也可以實驗十六進制來表示同一段數(shù)據(jù),雖然二進制與十六進制形式不同,將兩者的熵沒有改變,我們可以將任何數(shù)據(jù)的這種形式轉換稱為完美的無損轉換。

          沒錯,圖像這類數(shù)據(jù)也可以進行無損轉換。

          想象一下,你可以將任何隨空間或時間變化的數(shù)據(jù)集(比如圖像的亮度值)都轉為不同的坐標空間,假設現(xiàn)在我們有頻率坐標系(不是x-y坐標系),現(xiàn)在FreqX與FreqY是坐標軸,我們可以將圖像無損的轉換為頻率坐標系中,即將圖像換了一種表示形式且熵沒有改變。

          如下圖,我們將蘋果筆記本圖片轉為頻率坐標的表示

          看到頻率坐標系中的內(nèi)容,其中高亮的點是圖像中具有高信息含量的數(shù)據(jù),我們可以基于頻率坐標的展示,看出圖像中重要的部分與不太重要的部分,將不太重要的部分丟棄,則實現(xiàn)圖像的有損壓縮,如下圖所示:

          從圖中可知,我們丟棄頻率坐標中邊緣信息越多,圖像就越小,從而實現(xiàn)了圖像的壓縮。

          H.264利用了這個技巧來實現(xiàn)視頻中幀圖像的壓縮,但這還不夠。

          色度抽樣

          基于科學研究發(fā)現(xiàn),人類眼睛相應的腦區(qū)不太擅長分辨顏色的細節(jié),我們對亮度變化敏感,但對顏色的變化不敏感,如果我們丟棄圖像中的部分顏色,我們是感受不出變化的,所以我們需要一些方法來合理的丟棄圖像中的部分顏色信息,以此進一步壓縮圖像。

          在電視信號中,R+G+B顏色數(shù)據(jù)被無損轉為Y+Cb+Cr的形式來展示數(shù)據(jù),其中Y表示亮度(本質(zhì)是黑白亮度),Cb和Cr的顏色成分,RGB轉YCbCr,其信息熵是沒有變化的。

          為啥電視不直接使用RGB,而轉一層,使用YCbCr呢?其實是歷史原因。

          早期只有黑白電視,我們只需要使用Y信號便可完成數(shù)據(jù)的傳輸,隨后,彩色電視問世,進入彩色電視與黑白電視共存的年代,如果彩色電視使用RGB,那么就需要弄2個獨立的數(shù)據(jù)流,這很麻煩(成本、維護上都麻煩)。

          聰明的工程師決定將顏色信息編碼進Cb和Cr中,并將其與Y信息一同傳輸,這樣黑白電視只能看Y信息,而彩色電視內(nèi)部將YCbCr轉為RGB顯示則可。

          因為人眼對亮度變化敏感,但對顏色變化不敏感,所以我們可以將Cb、Cr壓縮,從而將圖像大小再減少一半,而人眼卻看不出差別。

          運動估計與補償

          前面幾種壓縮方式都是針對幀內(nèi)的,即針對圖像的,而視頻還有另外一個大的壓縮空間,那便是幀間信息(幀與幀之間)。

          H.264采用運動估計與補償?shù)姆绞絹韷嚎s幀間信息,從而極大減小視頻的大小。

          首先,我們知道,視頻由一系列幀按順序排列而成,而這些幀,有很大一部分信息是冗余的,比如我們拍攝30 fps的視頻,那么抽出視頻中的1秒,可以發(fā)現(xiàn)有30張圖像,這30張圖像,內(nèi)容通常是相近的,是否有辦法將這些冗余的信息丟棄掉來減少視頻大小呢?

          當然有,運動估計與補償便是解決這個問題的一種方案,為了理解,我從其他文章中(譯文之外的文章)選了一個例子。

          現(xiàn)在有一個視頻,記錄了臺球的運動。

          一個視頻,展開后,就是一系列的幀:

          有了視頻后,第一步,要對視頻中的相似幀分組,那怎么判斷某些幀相似呢?

          H.264編碼器會按順序逐次抽取兩個相鄰幀,然后按宏塊進行對比,計算兩幀相似度。

          這里涉及到宏塊這個新概念,什么是宏塊?其實就是H.264處理圖像時的窗口大小,比如有一張圖:

          H.264默認會按大小劃分出一個宏塊,當然,你也可以按、等大小來劃分。

          H.264編碼器通過宏塊掃描與宏塊搜索來判斷兩個幀之間的相似度,然后將相似的幀分為一組。

          對同一組幀,會做運動估計與補償。

          首先,拿出同一組的相鄰兩幀。通過宏塊掃描,發(fā)現(xiàn)圖像中有物體,便在另一幀圖像相同位置的周圍進行搜索,如果在另外一幀的圖像中,也找到該物體,則可以計算出物體的運行矢量。

          如上圖,計算出相鄰兩幀圖像中臺球的相差位置,計算出臺球的運行的方向和距離。

          H.264編碼器依次把每一幀中球移動的距離和方向都記錄下來,如下圖:

          計算出運動矢量后,將相同部分的數(shù)據(jù)丟棄,剩余的數(shù)據(jù)便是補償數(shù)據(jù),對于這一組幀,我們只需要存儲完整的第一幀數(shù)據(jù)(稱為I幀)和補償數(shù)據(jù)便可以還原出完整原始數(shù)據(jù)了,通過這種做法,幀間大量冗余數(shù)據(jù)被壓縮。

          運動估計與補償算法壓縮了視頻大小,但也會帶來一些小問題,比如:

          當我們在視頻網(wǎng)站上瀏覽視頻時,如果錯過了一段內(nèi)容,想往回點擊,再次播放時,網(wǎng)站通常會停頓幾秒。這些內(nèi)容剛剛已經(jīng)緩存下來了,只是我沒看,想倒回去看,為何還會停頓,直接讀緩存信息不就行了?

          當你跳轉視頻到某個任意幀時,H.264的解碼器必須重新做所有的計算,從而得到運動矢量和補償數(shù)據(jù),并將這些數(shù)據(jù)加到你當前幀中。這個計算壓力是比較大的,所以會停頓一下,從而影響你的體驗。

          熵編碼器(Entory Coder)

          剛剛的描述中,我們簡化了獲取運動矢量和補償數(shù)據(jù)的過程,實際上,H.264編碼器將幀分組后,會將組中的第一幀作為I幀,然后使用兩種方式去獲取運動矢量,一種是P幀,一種是B幀。

          P幀只會與前一幀進行對比來獲得數(shù)據(jù),而B幀會對前后的幀都進行對比來獲得數(shù)據(jù)。

          在實際的視頻中,幀變化時,很可能會出現(xiàn)幾個宏塊掃描對比得出的運動矢量是相同的情況,這便造成了數(shù)據(jù)冗余。

          熵編碼器會處理這種數(shù)據(jù)冗余的情況,這是一種無損轉換,不會損失數(shù)據(jù),但這種轉換減少了存儲相同數(shù)據(jù)所需要的空間,從而減小視頻大小。

          結尾

          如果原始視頻的分辨率是,時長5秒,每秒60幀,那么原始視頻的大小為:,而壓縮后,視頻會變?yōu)?75kb,真讓人驚嘆,真的就是魔法。

          H.264有幾十年的研究歷史,本文只是簡單化的描述了其中的工作,但有很多細節(jié)并沒有展示,H.264也是經(jīng)過多年發(fā)展,慢慢優(yōu)化成當前形態(tài)的。

          我是二兩,我們下篇文章見。

          本文參考:

          • [H.264 is Magic]   https://sidbala.com/h-264-is-magic/
          • [視頻壓縮原理]   https://github.com/733gh/Android-Notes/blob/master/android/%E8%A7%86%E9%A2%91%E5%8E%8B%E7%BC%A9%E5%8E%9F%E7%90%86.md



          掃碼即可加我微信


          --End--

          1、想領取贈書,加我微信,朋友圈不定期送書;

          2、想咨詢學習,加我微信,每次咨詢僅9.9元;

          3、更多需求(學習 代碼 視頻剪輯),都可以加我微信,歡迎咨詢。


          掃碼即可加我微信


          分享

          收藏

          點贊

          在看

          瀏覽 36
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级成人黄色片 | 无码性爱视频 | 青青草自拍偷拍 | 国产一级a爱做片免费看 | 一级毛片a一级毛片免费看黄道婆 |