使用x264和libvpx-vp9控制FFmpeg的CRF

3
我有使用ffmpeg和x264的经验,并想与libvpx-vp9进行比较。我对一段原始视频进行了简单的单遍编码测试,使用了不同的crf设置和预设,同时使用了x264和libvpx-vp9。我对libvpx还不熟悉,但是我仔细遵循了thisthis的指导,但由于我可能错误地指定了参数组合,因此我得到的结果对我来说没有太多意义。
对于x264,我做了:
ffmpeg -i test_video.y4m -c:v libx264 -threads 1 -crf <crf> -preset <preset> -y output.mkv 

并获得了以下结果:

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

这对我来说很有意义,给定一个crf值,您可以得到PSNR的值,而改变预设可以降低比特率但增加编码时间。
对于libvpx-vp9,我做了以下操作:
ffmpeg -i test_video.y4m -c:v libvpx-vp9 -threads 1 -crf <crf> -cpu-used <effort> -y output.mkv 

首先,我认为从在线教程上得出的结论是-cpu-used选项等同于x264中的-preset。这个结论正确吗?如果是,那么和-quality有什么不同呢?此外,由于范围从-8到8,我认为负值是快速选项,而正值是最慢的选项。但我得到的结果非常令人困惑。
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

比特率非常低,而且 PSNR 似乎不受 crf 设置影响(并且与 x264 相比非常低)。-cpu-used 设置的影响非常小,并且 -2 和 2 看起来是相同的选项。我错过了什么?我期望 libvpx 花费更多时间进行编码(这绝对是真的),但同时也要进行更高质量的转码。我应该使用哪些参数来与 x264 进行公平比较?
编辑:感谢 @mulvya 和这个 doc,我发现要在 libvpx 中使用 crf 模式,我必须添加 -b:v 0。我重新运行我的测试,我得到:
    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

通过添加-b:v 0,PSNR和比特率显著提高。


对于VP9,编码为CRF时需要添加“-b:v 0”。 - Gyan
谢谢!我会编辑问题。 - igon
1个回答

3

-speed参数的负值意味着有一个截止时间,但在接近零的速度设置下,它没有影响。对于更快的编码,请使用远离零的-speed值(例如4或6)。您还可以考虑使用线程。

-quality已被弃用,不应再使用(根据代码注释)。


嗨@Ronald,你能再详细解释一下当你说负速度“意味着截止日期”时是什么意思吗?我进行了更多的测试,改变了crf和speed参数,发现负速度设置产生的结果(以PSNR和比特率为准)与正速度相同,但完成所需时间更长。 - igon
这意味着有一个定时器在计算编码每个超块(64x64像素)需要多长时间,如果超过截止日期,它将中止编码并丢弃该帧。但是,您没有设置截止日期,因此使用默认值(无限制),这意味着它永远不会中止编码该帧。所以,它运行一些额外的代码(使其变慢),但从来不使用那些结果。截止日期主要对实时通信(RTC)应用程序有用。 - Ronald S. Bultje
明白了。谢谢! - igon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接