XviD 的 VHQ 模式做的第二件事情,是 FFMPEG 裡面沒有的,但是這個功能還是要從 FFMPEG 談起。
FFMPEG 可以讓你自行選擇動作估計(ME)的時候使用的「比對最小誤差」的計算方法。
當我們尋找誤差最小的參考對象時,要怎麼比較哪個參考位置的誤差是最小的呢?
一般我們是使用上面提到的 SAD,將兩個方塊的像素值相減,取絕對值,然後把 16x16 所有的點相減的結果加起來,作為總和的誤差。
這個計算的方法比較簡單,速度很快,效果也很不錯。
但是 FFMPEG 還提供了其他各種的比較方法讓你作測試,有:
0. SAD: sum of absolute differences,計算法如上所述
1. SSE: sum of squared errors,和 SAD 差不多,但是不是取絕對值,而是平方,計算複雜度高一點
2. SATD: sum of absolute hadamard transformed differences,將像素值先作 hadamard 轉換,然後再比較兩個方塊 hadamard 轉換後係數的絕對值差值。這是 H.264 建議使用的做法,計算複雜度又比 SSE 高
3. DCT: sum of absolute dct transformed differences,先作 DCT 轉換,然後比較 DCT 係數的絕對值差值,理論上是最精確的比較法,但是計算複雜度最高
4. PSNR: sum of the squared quantization errors,計算量化誤差的平方總和
5. BIT: number of bits needed for the block,計算此方塊實際所需的 bit 數
6. RD: rate distoration optimal,利用 Lagrangian 算式找出 rate-distortion 的最佳平衡點
實驗證明,次像素的動作檢索如果使用比較精確的比對方法,例如 SATD/DCT,品質會提高(這個同時是 H.264 建議的方法)。
同時固定碼率下,BIT/RD 的比對法也會提升品質。
另外 SSE 似乎對動畫類型的影片有最好的效果。
XviD 的開發人員看到 FFMPEG 不錯的實驗結果,也開始著手開發類似的高品質模式。
sisKin 一開始是打算使用 DCT 比對法(因為他說雖然 DCT 比 SATD 複雜,但是他發現實際上壓縮的時候最耗時的動作不是在 CPU 的計算上,而是在等待記憶體的存取上,所以使用 SATD/DCT 的速度應該不會差太多),結果後來是使用 BIT 比對法,比較實際上所需的 bit 數最小的。
以前曾說過 ME 的時候做次像素的動作檢索,例如 Quarter Pixel,可以提高壓縮率,但是那時沒仔細說 Quarter Pixel 是怎麼做的。
如果我們一開始的時候就把整個畫面內插,補出 1/4 的像素,然後在這個畫面上作檢索,這樣一定會很慢很慢,因為要搜尋、比對的位置變得很多,範圍很大,而且也很沒有效率。
所以實際上做的時候,我們是先做整數像素的搜尋,找出整數像素上誤差最小的位置,然後再內插補出這個位置周圍的 1/2 像素,訂出八個新的搜尋位置,如下圖
代碼:
y x y x y
x x x x x
y x y x y
x x x x x
y x y x y
y: 整數像素
x: 1/2 像素
中間的 y: 找出來誤差最小的整數像素位置,也就是誤差最小方塊的左上角頂點位置
紅色: 新的次像素比對位置
這樣我們就只要比對這八個新位置和原來的整數像素位置哪個誤差最小,就可以找出 1/2 像素精度誤差最小的位置。
這麼一來就不用內插計算那麼多的點,也不用比對那麼多的次數,是不是比較有效率呢?
做完 1/2 Pixel 之後,我們可以繼續再做 1/4 Pixel 精度的新位置比對,依此類推。