陸陸續續學習H264有一段時間了,曾經以為自己可以在這方面大有作為,但是越是學習越發現,根本不存在能夠大幅度提升H264效能的方案,對於我這種水平的人來講。初次學習,概念的理解仍然很困難。在這裡我只是簡單淺顯的講一講我最近的讀書學習感想。

       首先推薦三本書,《新一代視訊壓縮編碼標準H.264(畢厚傑)》,《h264和mpeg-4視訊壓縮:新一代多媒體的視訊編碼技術》,《H264標準中文版》。

       H264是什麼?H264是一種視訊流的標準,與MP4、FLV等的區別在於,MP4裡面可以包含H264資訊和音訊資訊和其他的視訊的屬性資訊,所以無論H264放在MP4檔案裡還是放在FLV裡面,H264就是H264,是視訊的一種格式,就像MP3格式的音訊,無論放在MP4檔案中還是放在FLV檔案中,它都是MP3。

       我是在2015年末的時候學習H264的,對於這個時間來講H264不是新技術,因為H265慢慢的普及之中,我相信H265在將來的一天會取代H264。那麼我學習H264的原因是什麼呢?瞭解視訊編解碼原理,據我瞭解H265只是對H264細節的改進,從H261開始視訊編碼的框架大體上是相同的。      

       下面這幅圖是取自《新一代視訊壓縮編碼標準H.264(畢厚傑)》中,這幅圖將會伴隨著學習H264的全過程,我沒有辦法用簡短的語言清晰的描述下圖中的清晰含義,因此寫下本篇文章對其進行解釋。

       初次看來覺得這幅圖比較複雜,的確有些複雜,不過,我接下來要描述的是概念,或者叫名詞解釋,之後再對這幅圖進行詳細的解釋。

       逐行掃描:影象可以看做是一個二維陣列,逐行掃描是指在獲取影象的時候從第0行開始,之後第1行....直至最後一行對影象進行取樣。

       隔行掃描:將一副影象按照奇偶分成兩部分,0,2,4,6,8.....,和1,3,5,7,9......。這樣分成兩部分獲取影象資料,那麼一副影象因此可以分成兩個部分,我們成為場,偶數行所構成的場成為頂場,奇數行構成的場成為底場。

       幀:經過逐行掃描獲得的影象資料稱為幀。

       場:經過隔行掃面獲得的影象資料稱為場。

       影象:一幀或一場成為一幅影象。

       條帶:一幅影象內包含至少一個條帶。

       巨集塊:一個條帶內包含若干個巨集塊。

       預測編碼:視訊描述的是連續的影象的集合。經過大量的統計表明,前後兩幅影象中有大量的資料是一樣的,也就是存在著冗餘資料,那麼使用當前影象對前一張影象做“減法”,獲得兩個影象的“差值”。那麼只需要“差值”即可從前一幅影象中獲得當前的影象資訊。這個差值我們稱之為殘差。並且這個差值可以看做是二維陣列即看做是一個二維矩陣。使用一些數學上的方法對矩陣進行變換達到一定的壓縮目的,一般我們常用的數學方法是DCT,也叫作離散餘弦變換,變換的結果我們再次進行取樣,比如:DCT變換結果中的值範圍是從0,1000,那麼我們用0,10去表示這個範圍。這個過程叫做取樣。比如離散餘弦變換後的結果是{0,200,300,800,801,900,1000},我們對其進行重新取樣之後可以用以下序列替換{0,2,3,8,8,9,10}。這樣可以達到壓縮的目的。之後再對量化後的序列進行無失真壓縮(熵編碼)。

       預測編碼是對應的上圖中最上面一行的過程,當前幀Fn和前一幀F'n-1計算出殘差Dn,經過變換T,經過量化Q,重新排序,之後進行熵編碼得到了壓縮的影象資料。

       差分脈衝編碼DPCM:當前畫素為X,左臨近畫素為A,上臨近畫素為B,上左臨近畫素為C。與X之間距離越近的畫素,相關性越強,越遠相關性越弱。以P作為預測值,按照與X的距離不同給以不同的權值,吧這項畫素的加權和作為X的預測值,與實際值相減,得到差值q,由於臨近畫素的相關性較強,q值非常小,達到壓縮編碼的目的。接收端把差值q與預測值相加,恢復原始值X。這個過程稱為差分脈衝編碼DPCM。當前畫素的實際值與預測值之間之間存在差值稱為殘差,對殘差記性量化後,得到殘差量化值。解碼輸出與原始訊號之間有因為量化而產生的量化誤差。

       運動估計:由於活動影象臨近幀中存在一定的相關性,因此將影象分成若干個巨集塊,並搜尋出各個巨集塊在臨近影象中的位置。並且得到巨集塊的相對偏移量。得到的相對偏移量稱為運動向量。得到運動向量的過程稱為運動估計。在幀間預測編碼中,由於活動影象臨近幀中景物存在一定的相關性,因此,可以將活動影象分成若干塊或巨集塊,並設法搜尋出每個塊或巨集塊在臨近幀影象中的位置,並得出亮著之間的控制元件位置相對偏移量,得到的相對偏移量就是通常所指的運動向量,得到運動向量的過程被稱為運動估計。運動向量和經過匹配後得到的預測誤差共同傳送到解碼端,在解碼端按照運動向量指明的位置,從已經解碼的臨近參考幀影象中找到相應的塊或巨集塊,和預測誤差相加後就得到了塊或巨集塊在當前幀中的位置。通過運動估計可以去除幀間的冗餘度,使得視訊傳輸的位元數大為減少,因此運動估計是視訊壓縮處理的一個重要組成部分。

       運動表示法:由於在成像的場景中一般有多個物體作不同的運動,如果直接按照不同型別的運動,將影象分割成複雜區域是比較困難的,最直接和不受約束的方法是在每個畫素都指定運動向量,這就是基於畫素表示法。對於任何型別影象都適用,但是需要顧及大量的未知量,並且解在物理上多是不正確的,除非在顧及過程中事假適當的物理約束。在具體實現的時候是不可能的,通常採用基於塊的物體運動表示法。

       塊匹配法:一般對於包含多個運動物體的景物,實際中普遍採用的方法是把一個影象幀分成多個塊,使得在每個區域中的運動可以很好地用一個引數化模型表徵。即將影象分成若干個nxn塊(如:16x16巨集塊),為每一個塊妱運動向量,並進行運動補償預測編碼。

       亞畫素位置內插:幀間編碼巨集塊中的每個塊或亞巨集塊分割區域都是根據參考幀中的同尺寸的區域預測得到的,他們之間的關係用運動向量來表示,由於自然物體的連續性,相鄰兩幀之間的塊運動向量不是以整畫素為基本單位的,可能是以1/4或1/8畫素等亞畫素作為單位的。

       運動向量中值預測:利用與當前塊E相鄰的左邊塊A,上邊塊B和右上方C的運動向量,取其中值來作為當前塊的運動向量。運動向量中值預測:利用與當前塊E相鄰的左邊塊A,上邊塊B和右上方C的運動向量,取其中值來作為當前塊的運動向量。
       空間域的上層塊模式運動向量:H264提供的塊尺寸有16x16,8x16,16x8,8x8,8x4,4x8,4x4,他們的影象分割區域分別定義為搜尋模式Model1-Model7.

       前幀對應塊運動向量預測:利用前一幀與當前塊相同座標位置的塊的運動向量作為當前塊的運動向量
時間域的臨近參考幀運動向量預測:由於視訊序列的連續性,當前塊再不同的參考幀中的運動向量也有一定的相干性。假設當前所在幀的時間為t,則當前在前面的參考幀t'中搜索.

       當前塊的最優匹配塊時,可以利用當前塊再參考幀t'+1中的運動向量來估計當前塊再幀t'的運動向量。

       變換編碼:絕大多數影象都有一個共同的特徵,平坦區域和內容緩慢變化的區域佔據了一幅影象的大部分,而細節區域和突變區域佔據較小部分。也就是說,影象中的低頻直流佔大部分,高頻區域佔小部分。這樣空間域的影象變換到頻域或所謂的變換域會產生相關性很小的變換系數,可以對其進行壓縮編碼。(關於時域頻域概念,本文中不加以詳細概述,請參考《傅立葉變換》和百度百科中《時域頻域》的相關解釋)