videoencodingffmpegx264libvpx

FFmpeg CRF control using x264 vs libvpx-vp9


I have some experience using ffmpeg with x264 and I wanted to do a comparison with libvpx-vp9. I tested a simple single pass encoding of a raw video, varying the crf settings and presets both with x264 and libvpx-vp9. I am new to libvpx and I followed this and this carefully but I might have still specified wrong combination of parameters since the results I get do not make much sense to me.

For x264 I did:

ffmpeg -i test_video.y4m -c:v libx264 -threads 1 -crf <crf> -preset <preset> -y output.mkv 

and obtained the following results:

codec  , settings                        , time        , PSNR      ,bitrate
libx264,['-crf', '20', '-preset', 'fast'],13.1897280216, 42.938337 ,15728
libx264,['-crf', '20', '-preset', 'medium'],16.80494689, 42.879753 ,15287
libx264,['-crf', '20', '-preset', 'slow'],25.1142120361, 42.919206 ,15400
libx264,['-crf', '30', '-preset', 'fast'],8.79047083855, 37.975141 ,4106
libx264,['-crf', '30', '-preset', 'medium'],9.936599016, 37.713778 ,3749
libx264,['-crf', '30', '-preset', 'slow'],13.0959510803, 37.569511 ,3555

This makes sense to me, given a crf value you get a value of PSNR and changing the preset can decrease the bitrate but increase the time to encode.

For libvpx-vp9 I did:

ffmpeg -i test_video.y4m -c:v libvpx-vp9 -threads 1 -crf <crf> -cpu-used <effort> -y output.mkv 

First of all I thought from tutorials online that the -cpu-used option is equivalent to -preset in x264. Is that correct? If so what is the difference with -quality? Furthermore since the range goes from -8 to 8 I assumed that negative values where the fast options while positive values the slowest. Results I get are very confusing though:

codec     , settings                      , time        , PSNR     ,bitrate
libvpx-vp9,['-crf', '20', '-cpu-used', '-2'],19.6644911766,32.54317,571
libvpx-vp9,['-crf', '20', '-cpu-used', '0'],176.670887947,32.69899,564
libvpx-vp9,['-crf', '20', '-cpu-used', '2'],20.0206270218,32.54317,571
libvpx-vp9,['-crf', '30', '-cpu-used', '-2'],19.7931578159,32.54317,571
libvpx-vp9,['-crf', '30', '-cpu-used', '0'],176.587754965,32.69899,564
libvpx-vp9,['-crf', '30', '-cpu-used', '2'],19.8394429684,32.54317,571

Bitrate is very low and PSNR seems unaffected by the crf setting (and very low compared to x264). The -cpu-used setting has very minimal impact and also seems that -2 and 2 are the same option.. What am I missing? I expected libvpx to take more time to encode (which is definitely true) but at the same time higher quality transcodes. What parameters should I use to have a fair comparison with x264?

Edit: Thanks to @mulvya and this doc I figured that to work in crf mode with libvpx I have to add -b:v 0. I re-ran my tests and I get:

    codec     , settings                                 , time        , PSNR     ,bitrate
libvpx-vp9,['-crf', '20', '-b:v', '0', '-cpu-used', '-2'],57.6835780144,45.111158,17908
libvpx-vp9,['-crf', '20', '-b:v', '0', '-cpu-used', '0'] ,401.360313892,45.285367,17431
libvpx-vp9,['-crf', '20', '-b:v', '0', '-cpu-used', '2'] ,57.4941239357,45.111158,17908
libvpx-vp9,['-crf', '30', '-b:v', '0', '-cpu-used', '-2'],49.175855875,42.588178,11085
libvpx-vp9,['-crf', '30', '-b:v', '0', '-cpu-used', '0'] ,347.158324957,42.782194,10935
libvpx-vp9,['-crf', '30', '-b:v', '0', '-cpu-used', '2'] ,49.1892938614,42.588178,11085

PSNR and bitrate went up significantly by adding -b:v 0


Solution

  • Negative values for -speed imply a deadline, but at near-zero speed settings, that has no effect. For faster encodes, use -speed values further away from zero (e.g. 4, or 6). You could also consider using threading.

    -quality is deprecated and should not be used (according to the code comments).