一個無聊的 MPEG-4 Codec 測試(內文圖很多!!)

除了不要把這裡當作電腦軟硬體診療室之外,什麼都可以聊!

版主: DearHoney

TMNEXT
神人
文章: 271
註冊時間: 2002-01-02 08:00
來自: 人畜同樂促進會

文章 TMNEXT »

開始做這個測試沒有多久,我就發現這個測試挺無聊的 ^^;
不過因為發現了一些奇怪的事情,原本的測試目的(找最佳的 MPEG-4 Codec)反而變得不重要,所以我最後還是硬著頭皮把它做完了。
這個奇怪的現象我想來想去找不出合理的解釋,所以我把測試結果貼上來,順便請大家一起來研究看看這個現象是什麼原因造成的。

測試的方法是取一段 sample clip,用各種 MPEG-4 Codec 壓縮,然後比較壓縮後的影像和原本影像的差距,計算每一張畫面的 PSNR(Peak-SNR)訊噪比,單位是 dB,訊噪比越高的和原來畫面的差距就越小,越接近原始畫面,代表壓縮的品質越好。
PSNR 的算式定義我就不詳述了,有興趣者可自行參考
http://bmrc.berkeley.edu/courseware/cs2 ... /psnr.html
PSNR 低於 25dB 的話,一般人都無法滿意這樣的畫質;高於 35dB,一般會認為畫質不錯;高於 40dB 以上,不定格注意看的話通常無法分辦和原圖有何不同。

因為剛好我正在壓一部動畫的 OP,所以想也沒想就拿這部 OP 來測試了,經過 24fps 補正,Lanczos3 Resize 縮小..等處理以後,就用 AviUtl 壓縮,然後要比較計算 PSNR 的時候... 我傻眼了,因為要和原本的影像比較,我必須拿 AviUtl 處理過之後的影像來比較,不能拿 DVD 上原始 720x480,YUV 4:2:0 的影像來比較,所以我最後只好轉成 VFAPI,比較 RGB 的 PSNR。
知道我在說什麼嗎?我的意思是,本來要測試的話,最好是直接原封不動的把原始 YUV 4:2:0 的影像送進 Codec 壓縮,然後比較壓縮後的 YUV 4:2:0 和壓縮前的 YUV 4:2:0 Data,這樣就不會經過 YUV 4:2:0(原始資料)--> RGB24(內插補點轉換為 RGB24 給 AviUtl 處理)--> YUV 4:2:0(Codec 壓縮)--> RGB24(解壓縮再展開,比較 PSNR),這麼多重的手續了。而且 YUV <--> RGB 轉換是有損失的,反覆的轉來轉去會喪失一些精確度。

不過檔案都已經壓好了,我實在沒力再重壓一遍 YUV 直入的版本,而且
1. 大家的原始影像都是 AviUtl 處理過之後的影像,和 AviUtl 的影像比較,大家的基準點還是都一樣
2. 影像最後要顯示,還是要轉為 RGB 才能顯示,所以 YUV 解壓縮展開為 RGB 之後再比較,也是很合理的
所以... 就這麼硬著頭皮測下去了(汗)
(所以這篇的參考價值不高,因此貼在聊天打屁區 :P

下面是測試結果
1. MS MPEG-4 V2
用ネペパ樣的 M4C plugin,設定是
rate: 32767, key: 9999, cc: 100, pixel: 28, diff: 12
2. FFVFW
CQ quantizer 2x,沒有用 B-Frame,keyframe 間距 250(應該設 240,我設錯了,不過算了 :P )ME 用 EPZS,high quality,4MV(一個 Macroblock 16x16 的像素方塊中,允許上下左右四個 8x8 的方塊各自尋找最匹配的參考方塊,總共有四個移動向量,理論上可以提高壓縮率),量化的方法採用 H.263(uniform quantization,畫面會比較模糊)
因為在我的電腦上 FFVFW VFW Codec 自己解碼會當機,所以我把 4CC 改成 XviD,由 XviD 的 Codec 來解碼
3. XviD Nic's build 9/10
quantizer 2x,key 250,EPZS^2,H.263
4. DivX 5.02 AviUtl
quantizer 2x,沒有用 B-Frame,slowest,key 250

前面的檔案都是用 AviUtl 壓的。我用的 AviUtl 0.98B 壓 DivX 5.02 開 B-Frame 的話會當掉,所以只好轉成 VFAPI,送給 VirtualDub 壓,同時沒有使用 B-Frame 的版本也用 VD 壓一個
5. DivX 5.02 VirtualDub
6. DivX 5.02 with B-Frame

測出來的 RGB-PSNR(RGB 三個分量的誤差總和)數據如下

代碼: 選擇全部

Comparing channel(s) RGB
Total frames processed: 2182

M4C: 34.4MB
                           Minimum   Average   Maximum
Mean Absolute Deviation:    0.0000    2.9154    8.6358
         Mean Deviation:   -1.4536   -0.7389   +0.0225
                   PSNR:   24.6355   36.9992  106.5268

FFVFW: 36.0MB
                           Minimum   Average   Maximum
Mean Absolute Deviation:    0.0000    3.5582    8.4511
         Mean Deviation:   -4.0049   -2.6206   +0.0000
                   PSNR:   26.6886   33.6259  106.5268

XviD: 38.3MB
                           Minimum   Average   Maximum
Mean Absolute Deviation:    0.0000    3.6458    8.3808
         Mean Deviation:   -3.9869   -2.8831   +0.0000
                   PSNR:   26.7289   33.5407  106.5268

DivX 5.02 AviUtl: 38.4MB
                           Minimum   Average   Maximum
Mean Absolute Deviation:    0.0000    2.9405  103.1112
         Mean Deviation:  -26.8836   -1.2053  +70.4096
                   PSNR:    6.0462   37.3114  106.5268

DivX 5.02 VirtualDub: 39.5MB
                           Minimum   Average   Maximum
Mean Absolute Deviation:    0.0000    3.9974    9.0646
         Mean Deviation:   -3.9360   -3.3034   +0.0000
                   PSNR:   24.5653   35.1597  106.5268

DivX 5.02 with B-frame: 32.3MB
                           Minimum   Average   Maximum
Mean Absolute Deviation:    0.0000    3.9233    9.0646
         Mean Deviation:   -3.9360   -3.0705   +0.0000
                   PSNR:   24.5653   35.2418  106.5268
這些數據不太有參考價值,請不要認真比較 ^^;
我後來有想到一個在現有的情況下,比較精確的比較方法。
先將原始影像轉為 YUV,然後設定各個 Codec 解碼輸出 YUY2 格式(除了 MS MPEG-4 V2 3920 Codec 以外。MS MPEG-4 V2 Codec 只能輸出 RGB,必需要再轉換為 YUV),然後只比較 Y-channel 的 PSNR,這樣就不會有內插補點演算法不同造成的精確度問題了。(一般播放使用 DirectShow Filter 走 DirectDraw Overlay,會直接丟 YV12 的 data 給顯示卡,由顯示卡統一做硬體色空間轉換,所以補點的效果各個 Codec 壓出來的都一樣,不像現在實驗中,由 Codec 自行展開為 RGB,不知道各個 Codec 內部展開的算法優劣,這樣比較就沒有意義了)
不過這個實驗等以後再做,現在重點不是這個 :P
上面的數據中,最大的 PSNR 有 106.5268dB 的,那是因為壓縮的畫面是一張全黑的畫面。
我發現 XviD 和 FFVFW(XviD 解碼)的顏色和原來差距較大,所以差不多每一張的畫面 PSNR 都輸 M4C。壓全白(RGB 255,255,255)的畫面測試,M4C 解出來是 RGB (254,254,254),XviD 和 FFVFW 都是 (253,253,253)。
另外我又發現 DivX 5.02 不用 B-Frame,以 AviUtl 壓出來有一個很奇怪的現象:

代碼: 選擇全部

M4C:
           Mean               Max    Max             
         Absolute     Mean    Pos.   Neg.            
 Frame     Dev.       Dev.    Dev.   Dev.  PSNR (dB) 
-----------------------------------------------------
   906    3.4166    -0.6048   29    -28     36.1130
   907    2.2439    -0.8765   39    -35     38.6011
   908    2.5717    -0.8202   40    -37     37.5100
   909    3.1709    -0.7919   40    -44     35.8069
   910    3.5057    -0.7287   41    -45     35.1616
   911    3.7912    -0.6942   45    -45     34.6511

DivX 5.02 AviUtl:
           Mean               Max    Max             
         Absolute     Mean    Pos.   Neg.            
 Frame     Dev.       Dev.    Dev.   Dev.  PSNR (dB) 
-----------------------------------------------------
   906    3.6055    -1.2993   33    -28     35.8181
   907    1.6161    -0.8691   28    -30     40.9100
   908   35.9429    +4.7657  255    -255     11.4417
   909    2.5504    -1.0653   31    -43     37.5625
   910    2.9446    -1.1254   30    -40     36.6907
   911    3.1894    -1.2157   43    -37     36.1986

Frame #907(從編號 0 開始算)是一張 keyframe,你會注意到 DivX 5.02 緊跟在 keyframe 之後的 #908 的 PSNR 非常慘,只有 11.4417dB!!
我覺得非常奇怪,檢查這張 #908 才發現,它的畫面變成和前面的那張 keyframe 一模一樣,也就是說 keyframe 重複顯示,出現了兩次。
這種現象每一個 keyframe 後面都會發生。
譬如原來畫面的順序是
1 2 3 4 5 6 7 8
3 是 keyframe,則壓縮後畫面會變成
1 2 3 3 5 6 7 8
3 重複出現兩次,而 4 則不見了,直接跳掉
所以畫面比對的時候差距才會那麼大,PSNR 才會那麼低。
這個 bug 是 DivX 5.01 的時候就有的,有用 B-Frame 的時候正常,但是如果不用 B-Frame 就會出現這種現象。我以為 DivX 5.02 已經修掉這個 bug 了(用 VD 壓不會有這種現象),沒想到用 AviUtl 壓竟然又會出現這個 bug。
所以我才會用 VD 也壓一個不使用 B-Frame 的版本來比較看看,沒想到這一試,又試出一個更詭異的現象,我怎麼想都想不通會什麼會這樣。
那就是... 同樣的設定,用 VD 壓出來的畫質竟然大輸給 AviUtl(請參照上面的數據,AviUtl 平均 PSNR 37.3114dB,VD 35.1597dB,不是只有少數幾張差距很大,而是每一張畫面都輸差不多 1.5~3dB)。
這這這... 這實在太神奇了,這怎麼有可能呢?
VD 壓的時候,是拿 AviUtl 的專案檔轉成的 VFAPI AVI 來壓縮的,同樣經過 AviUtl 處理。AviUtl 處理的時候是 RGB24,VFAPI 內部也一律都是以 RGB24 運作,所以不會做色空間轉換的處理,直接丟給 VD。我為了確認,還用 VD 開啟輸入的 VFAPI AVI 之後,不經任何處理直接輸出畫面到剪貼簿,儲存後和 AviUtl 的畫面比對 PSNR,結果兩者完全一樣。也就是說,壓縮的訊源,AviUtl 和 VD 是完全一樣的。
再者,VD 壓縮的時候,我試過 Fast recompression(直接丟原始的 data 給 Codec),Normal recompression(由 VD 先將格式轉換為 RGB,再丟給 Codec,一樣不經過 VD 的 Filter),兩種壓出來的結果都一樣。
測試全白的畫面,VD 壓出來是 (251,253,253),AviUtl 壓出來是 (255,255,255)
發現這樣的結果之後,我怕是我自己忙中有錯,不小心更動了設定而不自知,或是電腦太老了突然秀逗,所以隔了一天之後重開機再壓一次,結果還是一樣。
這這這... 實在太奇怪了,同樣的設定,同樣的訊源,壓出來結果卻不一樣,有人知道這是為什麼嗎?

下面是一堆圖,如果看不到請在圖的位置上按滑鼠右鍵,「顯示圖片」,多試幾次
Frame #1582 原圖
圖檔
M4C 壓縮後的圖。這是一張 keyframe。
圖檔
M4C 和原圖的差異(difference),僅顯示 Y(亮度)的差異。
圖檔
MS MPEG-4 keyframe 的預設值,quantizer 最低只能到 4x,所以只要是 keyframe 畫質都很慘。由差異圖可以看到,銳利線條旁邊都是斑斑點點的量化瑕疵。

FFVFW
圖檔
FFVFW 的差異圖
圖檔
H.263 的量化矩陣,線條、邊緣的部分都被削光了,畫面變得模糊。不過看起來很舒服 :P

XviD
圖檔
XviD 差異圖
圖檔
同樣,H.263 量化矩陣。

DivX 5.02 AviUtl 壓縮,沒有使用 B-Frame
圖檔
DivX 5.02 AviUtl 差異圖
圖檔
喔喔,看起來很不錯 :D

DivX 5.02 VD 壓縮,沒有使用 B-Frame
圖檔
DivX 5.02 VD 差異圖
圖檔
謎啊~~ .....

其他的圖,有機會再貼 :P
Kyochan
神人
文章: 750
註冊時間: 2001-04-11 08:00
來自: Eevolution World
聯繫:

文章 Kyochan »

嘖嘖嘖∼!好棒的測試啊!TMNEXT兄也在玩MPEG4壓縮啊! [b07]
給您的測試報告拍拍手∼! :tup:
頭像
kouyoumin
神人
文章: 1612
註冊時間: 2001-01-05 08:00
來自: 中正紀念堂
聯繫:

文章 kouyoumin »

<!-- BBCode Quote Start --><FONT COLOR=GREEN>PSNR 的算式定義我就不詳述了,有興趣者可自行參考
http://bmrc.berkeley.edu/courseware/cs2 ... /psnr.html
</FONT><!-- BBCode Quote End -->
請問測定PSNR有現成的軟體可用嗎?
(還是要自己寫? [XP] )
CCMC
大師
文章: 60
註冊時間: 2001-01-06 08:00
來自: 台中

文章 CCMC »

PSNR雖然常用,可是對人眼並不是很適合的量測標準,
一般人眼容易察覺的"壓不好"的地方大多在發生鋸齒邊緣的部份,
但是對均勻色塊的改變卻不易發現,
舉例說上圖中人物皮膚的顏色有一大片,如果還原後的亮度都差1,
那PSNR的結果一定很慘,可是誰能看出它改變了?
因此PSNR用在影像上就參考一下就好了,要是和你的直覺有出入,
也別太介意^^.

-------------
不過好像也沒聽過有更好的量測法...
Chord
神人
文章: 457
註冊時間: 2001-01-04 08:00
聯繫:

文章 Chord »

嗚啊~
不仔細看實在是不會有很明顯的差異…
我眼睛不好嗎?… [b09]
尤其是當影片是在動時,不太可能像這樣拿兩張靜態定格比較…
我比較好奇大動態時的效果 [b05]
TMNEXT
神人
文章: 271
註冊時間: 2002-01-02 08:00
來自: 人畜同樂促進會

文章 TMNEXT »

<!-- BBCode Quote Start --><FONT COLOR=GREEN>
PSNR雖然常用,可是對人眼並不是很適合的量測標準,
一般人眼容易察覺的"壓不好"的地方大多在發生鋸齒邊緣的部份,
但是對均勻色塊的改變卻不易發現,
舉例說上圖中人物皮膚的顏色有一大片,如果還原後的亮度都差1,
那PSNR的結果一定很慘,可是誰能看出它改變了?
因此PSNR用在影像上就參考一下就好了,要是和你的直覺有出入,
也別太介意^^.

-------------
不過好像也沒聽過有更好的量測法...

</FONT><!-- BBCode Quote End -->
有的。
測量影像品質一樣分為主觀測試和客觀測試兩種。
主觀測試就是用人眼去看,比較不同的圖片,然後由好到壞給分數,一般是根據 ITU-R Recommendation BT.500 用 MOS(Mean Opinion Score)給分。
客觀測試我想最常見的就是 PSNR,計算兩張圖 pixel 值的差距,這大概是修數位視訊課程的學生都會作的第一個作業 :P
PSNR 計算簡單,是最常用的測試方法,但是 PSNR 沒有辦法完全忠實的反映出人眼看到的視訊品質。所以現在新的測試方法,都引進了 HVS(Human Visual System)模型,會考慮人眼知覺的特性,提供更接近主觀測試的評量。例如 Tektronix 公司作的影像品質測試器,提供給電視台用來評估數位電視放送的服務品質(QoS)
http://www.tektronix.com/Measurement/cg ... television
所使用的評量方法,就是包含了 HVS 模型的 PQR 測試。
http://www.broadcastpapers.com/tvtran/T ... VQOS06.htm
能弄到這種機器來測當然是最好,不過.... 這只是一篇無聊的測試,沒辦法那麼專業 :P

HVS 模型主要考慮到幾種人眼的知覺特性
1. 人眼對亮度的絕對值差異(如亮度從 235 變成 230)比較不敏感,但是對亮度的對比差異(如一個區塊當中,有幾個點的亮度和其他部分很不一樣)則很敏感。
2. 人眼對亮度對比的差異比對色度對比的差異敏感。
3. 對比差異的敏感度會隨著空間頻率改變,空間頻率越高,對比差異的敏感度越低。
4. Masking,一個區塊的視覺特性會影到我們對他鄰近區塊的感知結果(Spatial Masking),前一個畫面的特性也會影響到下一個畫面的感知結果(Temporal Masking)。這種遮蔽的作用最為複雜,目前還沒有一套完整的公式可以描述這種人眼的視覺遮蔽效果。DivX 5.02 Pro 和 XviD 都有根據目前研究的 paper 加入 Masking 的壓縮工具。(Lumi masking/Psychovisual Enhancements)
5. 受限於生理結構,人眼對高動態的畫面比較不敏感。
6. ....
等等。
這些引進 HVS 模型的量測方法計算複雜度都非常高。
VQEG(Video Quality Experts Group)有對這些 HVS 的演算法作評估比較
http://www.vqeg.org/

下圖是使用 ANSI Recommendation 的 Spatial Information 測試方法
http://home.pchome.com.tw/health/iybbwd ... obel_s.jpg
圖很大。
作法很簡單,就是分別對原始影像和壓縮影像做 sobel 一次微分,然後比較兩者的 difference。(上圖我只有取水平垂直兩方向微分,八方向微分就... 算了,這只是一篇無聊的測試.... :P
經過 sobel 微分以後會把影像的邊緣抽取出來,人眼對這種差異比較敏感,所得到的結果會比較接近人眼的視覺感受。

至於動態的畫面,我現在是想做能顯示 Motion Vector 的畫面,比較一下各個 Codec 用的搜尋、比對方法和搜尋的範圍,以及最後壓出來的 frame 大小。
不過 DirectShow Filter 的部分還沒有搞定,所以... ^^;
像下面這樣
M4C 壓縮後解壓縮出來的畫面,下一張圖的參考畫面,Frame #1539
圖檔
原始畫面,要壓縮的畫面,Frame #1540
圖檔
M4C 作 Motion Estimation 之後,壓縮的畫面結果,Frame #1540,每一個方塊是一個 16x16 的 Macroblock,白線代表 Motion Vector。
圖檔
不過要能做到在同一張圖上顯示前後的畫面變動量..
如果看不出差異,可以下載回來用 ACDSee 切換著看。

以上的測試都是用 Avisynth 作的,不用自己寫程式啦 ^_^
(Avisynth 這一段程式碼有改寫成 MMX/SEE code,速度很快)
http://sourceforge.net/projects/avisynth2
你只要寫
#Displays differences on screen
clip1=AVISource("c:\clip1.avi")
clip2=AVISource("c:\clip2.avi")
Compare(clip1,clip2)
這樣的 script 語法就可以比較 PSNR 了。

不過... 重點是那個問題(為什麼 AviUtl 壓出來比較好?),怎麼都沒有人回答... ^^;;
豬哥
大師
文章: 153
註冊時間: 2001-01-05 08:00
來自: 台北縣

文章 豬哥 »

<!-- BBCode Quote Start --><FONT COLOR=GREEN>
不過... 重點是那個問題(為什麼 AviUtl 壓出來比較好?),怎麼都沒有人回答... ^^;;
</FONT><!-- BBCode Quote End -->

這個你要問魔人J(羅莉J)才對
JY
神人
文章: 827
註冊時間: 2001-12-06 08:00
來自: RF雜訊事記
聯繫:

文章 JY »

藍プベ青ウ.... [b12]
(剛剛在聽op)
不過感覺好像第一張脖子那邊壓的比較差一點?
fencer
初學者
文章: 2
註冊時間: 2002-09-20 08:00

文章 fencer »

基本上你的測試有很多東西都沒有控制好,
所以很難說AviUtl是不是比較"好".

舉個例來說,
第一個M4C和DivX 5.02 AviUtl的PSNR差約0.3 ~ 0.4 dB
但是bits相差了有4MB.
這4MB分到2182個frame裡,每個frame大概可以多出1900 Bytes,
換成bits大概是14~15 Kbits
如果給M4C的target bitrate高一點,我想M4C應該可以把PSNR追到差0.1 dB左右.
這樣的差距並不算太大.

另一方面,
讓AviUtl用較慢的Motion Estimation並不完全公平.
基本上只要用較快的ME都會有一小部份的quality loss,
這是因為並沒有辦法找到最好(使PSNR高)的Motion Vectors.

從這兩點看起來就很難說AviUtl是不是比較好.

如果你想做這一類的測試,
例如想找PSNR最好的codec.
那麼最好的codec應該是在target bitrate與quantizer都一樣的情形下,
用最慢(complexity最高)的motion estimation algorithm.

或者是在同樣target bitrate, 同樣的ME,而用其他的quantizer(非H.263的uniform quantizer)

無論如何,要達到較佳的PSNR(或quality),較大的檔案大小與較為複雜的演算法都是必需的.
(如果又小又快的話,那真的是很高明的方法喔! [b11] )
TMNEXT
神人
文章: 271
註冊時間: 2002-01-02 08:00
來自: 人畜同樂促進會

文章 TMNEXT »

<!-- BBCode Quote Start --><FONT COLOR=GREEN>
藍プベ青ウ.... [b12]
(剛剛在聽op)
不過感覺好像第一張脖子那邊壓的比較差一點?
</FONT><!-- BBCode Quote End -->
這首 OP theme 錄得好棒喔,聽起來很舒服,聲音很飽滿,又不會給人太大的壓力....我好久沒聽流行音樂了,不知道現在的技術是不是已經都這麼好了,每一首都差不多是這種水準,是我自己少見多怪? :P
不過第一次聽到的時候真的是嚇一跳...
第一張是用 M4C 壓的,那張是 keyframe,MS MPEG-4 如果你沒有用像 Nandub 這樣的工具去控制 Quantizer(DRF),則 keyframe 的最高品質只能用 Quantizer 4x,所以 MS MPEG-4 只要遇到 keyframe,畫質都很慘。其他幾張用別的 Codec 壓的一樣是 keyframe,不過都是固定品質(CQ, Constant Quality)Quantizer 2x 壓的,所以畫質都比 M4C 壓出來的好。
這也是為什麼魔人 j 壓 MS MPEG-4 V2 都不用 SCD(Scene Change Detection,偵測場景變換的地方插入 keyframe),除非發生灰色方塊,否則都不使用 keyframe。
另外,他不常用 VirtualDub,通常都用三神器(AviUtl, TMPGEnc, VideoMaid),所以... :P
我的 M4C 設定設得很隨便,沒有仔細調整參數,通常是要壓個幾遍,觀察灰色方塊檢出的情形,才能決定最好的檢出參數,儘量減少不必要的 keyframe。如下圖
圖檔
橫軸是 Y difference 亮度的差異,壓縮前和壓縮後的亮度差超過這個值便視為發生灰色方塊,目前設為 12。縱軸是亮度不同的 pixel 個數,目前是設為 28 個。左上是原圖,左下是檢出的灰色方塊。
根據檢出的畫面,檢查參數是否設得太低,連不是灰色方塊的畫面也檢出重壓為 keyframe。如下面這張圖
圖檔
此時就要調整設定為 Y diff: 15,也就是紅線的焦點超過藍色的圖形範圍。
不過我壓的時候沒有這樣調整,所以那個 M4C 的版本並沒有最佳化。
回覆文章