三個文件名以 erc 開頭的文件就是 EC 相關的文件。EC 的入口在 exit_picture 函數中,從 ercStartSegment 開始到 ercConcealInterFrame 結束。你自己做一個丟包之后的碼流,把程序跑起來跟蹤一下 EC 過程,慢慢分析代碼。
?
錯誤隱藏過程在整個幀全部解碼后,而且位于環狀濾波過程之后。
?????? 因為宏塊按掃描順序一行一行的編解碼,錯誤碼流會影響一連串的宏塊。因此,錯誤隱藏時,一般在當前幀解碼結束后,一列一列的錯誤隱藏。又由于人眼對圖像中間區域更敏感,故常從兩側邊緣開始對宏塊列進行掩藏,再逐漸向中央逼近,掩藏塊的運動矢量可以進一步為后續處理塊提供預測信息,從而這樣做使得圖像中間誤碼塊的恢復效果更好些。
?????? 所謂時域錯誤隱藏,就是根據正確解碼的鄰塊或前幀塊信息,推測得到合適的當前誤碼塊運動矢量。該運動矢量對應的參考塊直接拷貝至當前塊位置,就完成了錯誤隱藏過程。可見,關鍵問題在于如何找到合適的運動矢量。
??????? 最簡單的時域錯誤隱藏,就是設定每個錯誤宏塊的運動矢量都是零,這樣對于靜止塊和準靜止塊有效,對于運動較大的塊這出現了明顯的質量下降。一個稍稍改進的方法是:設定其運動矢量為鄰塊運動矢量、或它們的中值、或均值運動矢量,對于運動矢量場連續的序列效果較好,對于復雜運動序列依然效果較差。
?????? 改進方法1:得到多個候選運動矢量。比如,所有的鄰塊(4領域或8領域)運動矢量、它們的中值和均值、運動矢量、前一幀對應塊運動矢量....。然后根據匹配準則選擇代價最小的運動矢量。常用的準則就是邊界匹配法(BMA,boundary matching algorithm),就是選擇邊界像素和誤碼塊周圍相鄰的像素差值最小的塊。JM中正是這么做的,它的候選運動矢量只考慮了4鄰域的鄰塊運動矢量和零運動矢量。
??????? 改進方法2:方法1中的BMA準則,參與計算差異的像素個數較少,容易受到噪聲干擾。而且,如果本來宏塊邊界就存在物體邊緣,BMA的匹配效果將大打折扣。一個替代的準則是外邊界匹配法(EBMA,external boundary matching algorithm)。就是計算參考塊和誤碼塊的外部相鄰像素的差異。
?????? 改進方法3:方法1中得到的運動矢量,一般并不是誤碼塊的真實運動矢量。因此可以用加入運動估計過程,得到更佳的匹配塊。
?????? 改進方法4:以往的算法中,一般以整個宏塊為單元做錯誤隱藏(JM中就是這么做的)。可以將宏塊分成多個小塊(比如4個8*8塊),對每個小塊分別做錯誤隱藏,效果更好。但是這樣做,會出現一定的塊效應。因此,一個更折衷的方法是根據鄰塊的編碼模式推測誤碼塊的隱藏塊模式。
?????? 改進方法5:由于H.264中采用了更小的宏塊分割模式(最小支持到4*4),這樣使得編碼后的運動矢量場更佳連續,即塊與塊的運動矢量相關性更大。可以將誤碼塊分成16個4*4塊,每個4*4塊的運動矢量由周圍宏塊的運動矢量插值得到。一般是水平、垂直方向各插值一遍,然后取二者的均值。
?????? 改進方法6:在b、p幀中,也有一定的幀內編碼塊。同樣,錯誤隱藏的時候,也可以考慮空域錯誤隱藏方法。關鍵是如何判斷用空域還是時域隱藏。研究比較多的是,對I slice的宏塊(第一幀除外)也進行時域隱藏,前提是要判斷沒有出現場景轉換。
補充一點,時域錯誤隱藏也可以被應用于intra frame。h.264的對于intra-frame的weighted pixel averaging(WPA)插補錯誤隱藏算法不能取得良好的效果,時域錯誤隱藏往往能取得比WPA更好的結果。
Q1:風車,能不能推薦幾篇文章是講通過相鄰宏塊的編碼模式推測丟失塊類型的???
A:
A New Temporal Error Concealment Method for H.264 using Adaptive Block Sizes
A New Error Concealment algorithm for H.264 Video?? Transmission
Q:改進方法3:方法1中得到的運動矢量,一般并不是誤碼塊的真實運動矢量。因此可以用加入運動估計過程,得到更佳的匹配塊。不太明白如何進行運動估計,哪位高手指點下
A:就是說在做錯誤隱藏時采用一種類似于運動估計的方法,比如你有一個丟失的宏塊,你可以用這個丟失宏塊的臨近宏塊的邊界像素在前一幀中進行邊界匹配計算,在 一定的范圍內進行遍歷。最后得到的邊界匹配失真最小的宏塊就可以用來替代丟失的宏塊。這個過程 和運動估計 有些相似。