View Full Version : SSIM-SATD-Opt: Even better than SSIM-SAD-Opt™!
Dark Shikari
1st August 2007, 02:48
Settings used:
--subme 6 --bframes 1 --ref 1 --b-pyramid --partitions all --8x8dct --me umh --bime --b-rdo --direct auto --deblock 0:0
(weightb intentionally off to test the macroblock encoding ability only)
--qp 25 was used, with --qp 24 and 26 used to calculate dSSIM/dBitrate and dPSNR/dBitrate to adjust the results very slightly for the slightly differing bitrates (a few kbps) between each of the different optimizations.
Source: rushhour.yuv, denoised with fft3dgpu with sigma=3,beta=1,sharpen=0.7,precision=2, and then BilinearResized to half of its size, width and height.
All PSNR/SSIM values are the adjusted ones as explained above, though adjusted by very minimal amounts.
Original x264 (SAD):
SSIM: 0.9835223
PSNR: 43.738
SSIM-SAD-Opt (an average of 16000*(1-SSIM) and SAD):
SSIM: 0.9838156 (+1.81%)
PSNR: 43.737 (-0.001)
SSIM-SATD-Opt (an average of 16000*(1-SSIM) and SATD):
SSIM: 0.9839002 (+2.35%)
PSNR: 43.745 (+0.008)
:cool:
Download the executables used. (http://www.mediafire.com/?d4twnmn1lqg) (Cygwin builds)
Feel free to run this on the input of your choice, whether anime/cartoons, DVD source, noiseless source, etc, to see how well it works in various cases. Make sure to compare all three versions. If possible, use a --qp based method with numerical derivative compensation for the bitrate differences, but if that isn't possible either post the bitrates, or just use twopass mode with your normal encoding settings and see how much of an improvement it gives.
Note: the new SAD function is completely assembly-less, including the SATD and SSIM sections. This makes it very slow. Expect the encoding to be slow.
DeathTheSheep
1st August 2007, 16:28
Hooray! Dark Shikari does it again! :)
Preliminary results on the same anime clip I used previously (Bleach), QVGA resolution, the following commandline:
--qp 30 --no-fast-pskip --no-cabac --subme 7 --analyse p8x8,b8x8,i4x4,p4x4 --me umh
The results were interesting, to say the least:
Orig:
679KB
0.9678048 SSIM
38.768 PSNR
SAD
687KB
0.9683151 SSIM
38.784 PSNR
SATD
690KB
0.9683013 SSIM
38.762 PSNR
Uh oh! Here SATD does a bit worse than SAD in both metrics and outputs a higher filesize.
But not to worry, for I shall perform further testing!
[edit]More results with Dark Shikari's commandline:
--subme 6 --bframes 1 --b-pyramid --partitions all --8x8dct --me umh --bime --b-rdo --direct auto
Orig
1024KB
0.9824747 SSIM
42.248 PSNR
SAD
1023KB
0.9827618 SSIM
42.259 PSNR
SATD
1021KB
0.9827904 SSIM
42.241 PSNR
Again, quite interesting: here, on the very same clip but with different codec settings, SATD yields the least filesize, the most SSIM, but the least PSNR!
Some notes:
- ESA is still worse than any other ME mode in the optimized builds.
- SATD is 60% slower than SAD.
- Differences in codec settings favor SAD and SATD differently.
- In your commandline, Dark Shikari, both --ref 1 and your deblocking settings are redundant. :)
akupenguin
1st August 2007, 18:05
weightb intentionally off to test the macroblock encoding ability only
weightb is part of macroblock encoding. If you want to not run any motion estimation that won't be directly used as the inter prediction, then you'd better disable B-frames too. Because non-weighted biprediction is still an average of two motion-compensated signals, it's just a different average than weighted biprediction.
But I don't know why you'd want to disable that; after all, if a motion estimation algorithm doesn't work in the typical usage of x264 (with B-frames), then it's not a good algorithm. You might care why it does or doesn't work for the purpose of deciding which algorithm to try next, but not for comparing results.
Dark Shikari
1st August 2007, 18:08
weightb is part of macroblock encoding. If you want to not run any motion estimation that won't be directly used as the inter prediction, then you'd better disable B-frames too. Because non-weighted biprediction is still an average of two motion-compensated signals, it's just a different average than weighted biprediction.
I remember being told earlier to turn off --weightb to avoid different frametypes between the tests, so as not to test the ability of the codec to choose frametypes.
Wouldn't turning off bframes altogether yield a result which is thoroughly useless in regards to real-world encoding?
akupenguin
1st August 2007, 18:18
Weightb has nothing to do with frametypes.
You don't even need to turn off the options that do relate to frametypes: Run a 1st pass with b-adapt, then run multiple 2nd passes with CQP.
I know 2pass CQP sounds weird, but it is allowed, and this situation is exactly why I left it in.
Dark Shikari
1st August 2007, 18:23
Weightb has nothing to do with frametypes.
You don't even need to turn off the options that do relate to frametypes: Run a 1st pass with b-adapt, then run multiple 2nd passes with CQP.
I know 2pass CQP sounds weird, but it is allowed, and this situation is exactly why I left it in.
Wait, what do you mean weightb has nothing to do with frametypes?
I thought it was the option that chose whether to adaptively choose the number of frames? When I disabled it, I got exactly 1 I-frame, 100 P-frames, and 100 B-frames, which is what I'd expect with adaptive B-frame choice off.
Or is that b-adapt that does that?
DeathTheSheep
1st August 2007, 18:39
That's supposed to be b-adapt, letting the codec chose the amount of b-frames in a row up to your specified maximum. Weightb is just weighted bidirectional prediction for more accurate or better b-frame quality, is it not?
foxyshadis
2nd August 2007, 15:18
Would it be possible to get a (uniform) diff for this as well?
BTW, preliminary results with SAD show minimal gain on quantizers >28, and a virtual wash otherwise, on the two movies (with moderate grain) so far. No animation yet.
Dark Shikari
2nd August 2007, 15:29
Would it be possible to get a (uniform) diff for this as well?
BTW, preliminary results with SAD show minimal gain on quantizers >28, and a virtual wash otherwise, on the two movies (with moderate grain) so far. No animation yet.
I've found benefits with my standard settings, using --b-pyramid, --weight-b, --b-rdo, --bime, --subme 6/7, --trellis 1/2, --me hex/umh, etc. What settings are you using that cause no benefit over the original, and what source?
Also, are you comparing to the original x264 included, or 667b? This is based off an earlier x264 version, though the changes could be easily ported to 667b, which I'll do soon. Just make sure to compare to the same versions.
I've found reasonable gains (1-2%) on quantizers as low as 16 and as high as 30, I haven't tested outside that range though.
Sagittaire
2nd August 2007, 15:34
Source: rushhour.yuv, denoised with fft3dgpu with sigma=3,beta=1,sharpen=0.7,precision=2, and then BilinearResized to half of its size, width and height.
Where I can find this source ... ???
akupenguin
2nd August 2007, 15:36
ftp://ftp.ldv.e-technik.tu-muenchen.de/pub/test_sequences/
Dark Shikari
2nd August 2007, 15:38
ftp://ftp.ldv.e-technik.tu-muenchen.de/pub/test_sequences/
Also note I used the 1080p version.
DeathTheSheep
2nd August 2007, 16:05
I used baseline profile, which means no b-frames (obviously), but also a slightly more restrictive partition search (like no 8x8dct or adaptive DCT), and no CABAC, meaning no Trellis either. Additionally, I only use 1 reference because it eats less mobile processor time, believe it or not.
I posted my commandline above, by the way, if you want to take a look.
And yes, I didn't compare x264 versions across revision lines; I stuck exactly to the ones in your pack (and even if I hadn't, the changes since ~650 were only speed/compiler/compatibility changes anyway).
The source, again, was a dark, nighttime anime scene from Bleach, of 320x240 resolution and 23.976fps, with smooth motion (zooms and pans), stills (talking), and animation motion (pure cartoon).
Once I turned on B-frames and CABAC, things changed, and I did get slightly better SSIM and lower PSNR (again, look at my test post, which was edited considerably since I first made it). But otherwise, in normal usage, --b-pyramid, --weight-b, --b-rdo, --bime, --trellis 1/2, etc are all useless in my case, since I can't use them anyway.
If you ask why I even bother to use AVC at all without taking "full" advantage of it...
Well, x264, even in baseline profile, beats out ASP (XviD) at its maximum profile and settings. And the inloop deblocking makes it irresistible for handheld, PDA, Pocket PC, PSP, iPod, Quicktime, Standalone, etc compatibility, even though ASP solutions exist for most of these. Since I go with mobile media a lot, this compatibility is a necessity.
akupenguin
2nd August 2007, 17:20
like no 8x8dct or adaptive DCT
They're the same. Well, I suppose one could use non-adaptive 8x8dct, but x264 doesn't, and even then saying "no 8x8dct" would be sufficient.
DeathTheSheep
2nd August 2007, 17:24
Right, should have said "like no 8x8dct/adaptive DCT" ;)
Come to think of it, would there be any benefit to using a non-adaptive transform anyway?! :)
akupenguin
2nd August 2007, 17:41
Benefit other than speed? no. But I've seen some content that used 8x8dct on >90% of macroblocks, so you might not always lose much by disabling adaption. Not that there's much speed to be gained either - x264's non-rd dct adaption is just 2 evaluations of satd.
foxyshadis
2nd August 2007, 20:40
Also, are you comparing to the original x264 included, or 667b? This is based off an earlier x264 version, though the changes could be easily ported to 667b, which I'll do soon. Just make sure to compare to the same versions.
That was why I wanted a patch.
commandline 1:
--crf x --keyint 400 --ref 6 --mixed-refs --no-fast-pskip --bframes 5 --b-pyramid --b-rdo --bime --weightb --direct auto --filter -1,0 --subme 6 --trellis 2 --analyse all --8x8dct --vbv-maxrate 25000 --me umh --threads auto --thread-input --progress --no-dct-decimate --output "V:\video\work\tiffany's.mkv" "V:\video\work\tiffany's.avs" --aq-strength 0.3
commandline 2 (not done testing):
--crf x --keyint 150 --ref 4 --mixed-refs --no-fast-pskip --bframes 2 --b-pyramid --bime --weightb --direct auto --filter -1,0 --subme 6 --analyse all --8x8dct --vbv-maxrate 25000 --me umh --threads auto --thread-input --progress --no-dct-decimate --output "V:\video\work\tiffany's.mkv" "V:\video\work\tiffany's.avs"
I'm not going to bother testing other variations until I've tested things I actually use. I'm plotting bitrate vs normalized ssim (and psnr separately) and looking for peaks and dips by eye, since comparisons are tricky otherwise.
Dark Shikari
2nd August 2007, 21:12
That was why I wanted a patch.
commandline 1:
--crf x --keyint 400 --ref 6 --mixed-refs --no-fast-pskip --bframes 5 --b-pyramid --b-rdo --bime --weightb --direct auto --filter -1,0 --subme 6 --trellis 2 --analyse all --8x8dct --vbv-maxrate 25000 --me umh --threads auto --thread-input --progress --no-dct-decimate --output "V:\video\work\tiffany's.mkv" "V:\video\work\tiffany's.avs" --aq-strength 0.3
commandline 2 (not done testing):
--crf x --keyint 150 --ref 4 --mixed-refs --no-fast-pskip --bframes 2 --b-pyramid --bime --weightb --direct auto --filter -1,0 --subme 6 --analyse all --8x8dct --vbv-maxrate 25000 --me umh --threads auto --thread-input --progress --no-dct-decimate --output "V:\video\work\tiffany's.mkv" "V:\video\work\tiffany's.avs"
I'm not going to bother testing other variations until I've tested things I actually use. I'm plotting bitrate vs normalized ssim (and psnr separately) and looking for peaks and dips by eye, since comparisons are tricky otherwise.
The only file modified is pixel.c, and the only change is the stuff at the top (new function + function declaration + changed SAD function) and the commented-out ASM references at the bottom.
If not for the very slight difference between the 65x and 667 pixel.c you could just copy-paste over the file.
foxyshadis
2nd August 2007, 22:11
If not for the very slight difference between the 65x and 667 pixel.c you could just copy-paste over the file.
Sure, but as far as I can tell you never posted that file, only the SAD & SSD variations.
Do you mean that the new SATD function is a clone of the new SAD?
Dark Shikari
2nd August 2007, 22:53
37,66d36
< static int pixel_satd_wxh( uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2, int i_width, int i_height );
<
< int ssim_for_sad(int lx, int ly, uint8_t *pix1, int i_stride_pix1, uint8_t *pix2, int i_stride_pix2 )
< {
< int x, y;
< uint32_t s1=0, s2=0, ss=0, s12=0;
< for( y = 0; y < ly; y++ )
< {
< for( x = 0; x < lx; x++ )
< {
< int a = pix1[x];
< int b = pix2[x];
< s1 += a;
< s2 += b;
< ss += a*a;
< ss += b*b;
< s12 += a*b;
< }
< pix1 += i_stride_pix1;
< pix2 += i_stride_pix2;
< }
< x264_emms();
< int ssim_c1 = (int)(.01*.01*255*255*lx*ly + .5);
< int ssim_c2 = (int)(.03*.03*255*255*lx*ly*(lx*(ly-1)) + .5);
< int vars = ss*ly*lx - s1*s1 - s2*s2;
< int covar = s12*ly*lx - s1*s2;
< float result = (float)(2*s1*s2 + ssim_c1) * (float)(2*covar + ssim_c2)
< / ((float)(s1*s1 + s2*s2 + ssim_c1) * (float)(vars + ssim_c2));
< return 16000*(1-result);
< }
71,73d40
<
< //This is a rewritten "SAD" function that actually uses a combination of SATD (Hadamard), SSIM, and SAD.
<
78c45
< int sad = 0; \
---
> int i_sum = 0; \
80,81d46
< int satd = pixel_satd_wxh( pix1, i_stride_pix1, pix2, i_stride_pix2, lx, ly); \
< int ssim = ssim_for_sad(lx,ly,pix1, i_stride_pix1, pix2, i_stride_pix2);\
86c51
< sad += abs( pix1[x] - pix2[x] ); \
---
> i_sum += abs( pix1[x] - pix2[x] ); \
91c56
< return (ssim+satd)/2; \
---
> return i_sum; \
93a59
>
518c484
< /*if( cpu&X264_CPU_MMX )
---
> if( cpu&X264_CPU_MMX )
521c487
< }*/
---
> }
525,527c491,493
< //INIT( sad, _mmxext );
< //INIT( sad_x3, _mmxext );
< //INIT( sad_x4, _mmxext );
---
> INIT( sad, _mmxext );
> INIT( sad_x3, _mmxext );
> INIT( sad_x4, _mmxext );
552,553c518,519
< //pixf->sad[PIXEL_16x16] = x264_pixel_sad_16x16_sse2;
< //pixf->sad[PIXEL_16x8 ] = x264_pixel_sad_16x8_sse2;
---
> pixf->sad[PIXEL_16x16] = x264_pixel_sad_16x16_sse2;
> pixf->sad[PIXEL_16x8 ] = x264_pixel_sad_16x8_sse2;
562,563c528,529
< //pixf->sad_x3[PIXEL_16x16] = x264_pixel_sad_x3_16x16_sse2;
< //pixf->sad_x3[PIXEL_16x8 ] = x264_pixel_sad_x3_16x8_sse2;
---
> pixf->sad_x3[PIXEL_16x16] = x264_pixel_sad_x3_16x16_sse2;
> pixf->sad_x3[PIXEL_16x8 ] = x264_pixel_sad_x3_16x8_sse2;
565,566c531,532
< //pixf->sad_x4[PIXEL_16x16] = x264_pixel_sad_x4_16x16_sse2;
< //pixf->sad_x4[PIXEL_16x8 ] = x264_pixel_sad_x4_16x8_sse2;
---
> pixf->sad_x4[PIXEL_16x16] = x264_pixel_sad_x4_16x16_sse2;
> pixf->sad_x4[PIXEL_16x8 ] = x264_pixel_sad_x4_16x8_sse2;
607c573
< /*pixf->sad[PIXEL_8x8] = x264_pixel_sad_8x8_vis;
---
> pixf->sad[PIXEL_8x8] = x264_pixel_sad_8x8_vis;
620c586
< pixf->sad_x4[PIXEL_16x16] = x264_pixel_sad_x4_16x16_vis;*/
---
> pixf->sad_x4[PIXEL_16x16] = x264_pixel_sad_x4_16x16_vis;
Diff for 667b.
Dark Shikari
2nd August 2007, 22:53
nevermind
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.