1. 视频质量评价
2. VMAF
2.1. 什么是VMAF
2.2. VMAF的作用
3. VMAF安装
3.1. 仅安装vmaf
3.2. FFmpeg上支持vmaf
没有安装ffmpeg
最新版本的ffmpeg已经支持了vmaf,可以直接安装:brew install ffmpeg如果一定要自己build,下载ffmpeg代码,进入目录后执行configure时增加--enable-libvmaf参数。
./configure --enable-libvmaf ......已经安装了ffmpeg
这部分同学我建议删了重装ffmpeg,省时省心省力,步骤如上。
4. VMAF使用
本文主要介绍借助ffmpeg来执行vmaf这种方式。当开启vmaf的ffmpeg安装好后,就可以通过命令行来调用执行。命令支持很多参数,官网上也列举了一部分基本参数,大家可以查看参数说明。
这里,我们结合场景对一些常用参数进行说明,包括一些上面没有列举的参数。
4.1. 基本命令
输入
我们的目的是为了评价视频转码前和转码后的质量,所以参数至少需 要两个视频如下:original.mp4: 原视频
encoded.mp4: 编码后的视频
输出
因为我们不需要生成什么视频文件,所以将输出设置为标准输出(-),而标准输出又需要-f参数指定输出格式,这里也不需要什么特定的格式,所以可以设置为根据输入选择(null),这样输出这部分就是-f null -过滤器
指定复杂过滤器参数-fileter_complex
或-lavfi
,过滤器名称libvmaf。
此时我们拼接了一个最基本的命令:
ffmpeg -i original.mp4 -i encoded.mp4 -lavfi libvmaf -f null -
原视频和编码后的视频先后顺序无所谓,但后面会有一些对视频的处理操作,你必须知道它们哪个是哪个。
4.2. 指定模型
libvmaf WARNING could not read model from path: "/usr/local/share/model/vmaf_v0.6.1.pkl"
libvmaf WARNING pkl model files have been deprecated, use json
libvmaf ERROR problem loading model file: /usr/local/share/model/vmaf_v0.6.1.pkl
前文已经提到,vmaf是结合机械学习实现的一下评价体系,提到机械学习,你可能立刻会想到需要大量样本来训练模型,的确vmaf支持自己训练模型,但同时也内置了很多已经训练好的模型,vmaf_v0.6.1就是其默认模型。vmaf的内置模型在/yourpath/vmaf/model中:

回到刚刚的报错上,很显然是找不到默认的模型文件,我们可以在过滤器中指定一下:
ffmpeg -i original.mp4 -i encoded.mp4 -lavfi libvmaf=model_path=../model/vmaf_v0.6.1.json -f null -
此时计算就可以正常执行了。如果是想使用手机端的默认模型,可以指定phone_model:
ffmpeg -i original.mp4 -i encoded.mp4 -lavfi libvmaf=model_path=../model/vmaf_v0.6.1.json:phone_model=1 -f null -
4.3. 指定log文件
VMAF score: 89.067879
更多的信息需要在过滤器中指定日志文件,通过log_fmt指定日志格式,建议用xml,比较容易观察,通过log_path指定输出路径。如果不需要文件,也可以直接指定到标准输出:
ffmpeg -i original.mp4 -i encoded.mp4 -lavfi libvmaf=model_path=../model/vmaf_v0.6.1.json:log_fmt=xml:log_path=/dev/stdout -f null -
执行此命令,你会发现多了很多输出,这个执行结果我们放到最后说。
4.4. 需要增加处理的场合
当视频分辨率不一致时
当我们传入的两个视频分辨率不一致时,会得到报错:Width and height of input videos must be same如提示所说,vmaf要求传入两个视频分辨率一致。但是,在视频编码的过程中,我们经常会改变视频的分辨率,所以不可以避免的我们需要处理分辨率不一致的情况。很简单,统一分辨率要么把大分辨率的视频变小(下采样),要么把小分辨率的视频变大(上采样)。
下采样:假设原图分辨率为W * H,缩小S倍,分辨率为W/S * H/S,那么我们需要将原图S * S区域内的像素取均值,成为一个像素;
上采样:采用内插值算法增补像素,将图像放大。回到例子中,原视频(original)分辨率为1280*720,编码后的视频(encoded)分辨率为1024*576,我们分别看看上下采样的命令和执行结果:
上采样:ffmpeg -i original.mp4 -i encoded.mp4 -lavfi "[1:v]scale=1280:720[encoded];[0:v][encoded]libvmaf=model_path=../model/vmaf_v0.6.1.json:log_fmt=xml:log_path=/dev/stdout" -f null -解释一下,[x:v]的意思是取传入的第x+1个视频的视频流,然后变换到1280*720,并将此操作后的结果命名为[encoded],然后我们将第一个视频的视频流[0:v]和处理过后的[encoded]一同传入之前设置的过滤器libvmaf。
这里得到的vmaf值为:83.330639。
下采样:ffmpeg -i original.mp4 -i encoded.mp4 -lavfi "[0:v]scale=1024:576[origin];[origin][1:v]libvmaf=model_path=../model/vmaf_v0.6.1.json:log_fmt=xml:log_path=/dev/stdout" -f null -这里得到的vmaf值为:85.817568。我们只能说对于此视频来说差别不大,但建议还是优先采用下采样。
当PTS不一致的时候
PTS(Presentation Time Stamp)标识某一帧的显示时间,因为有I、P、B帧的存在,我们需要保证某帧不在某帧前显示,所以才有了PTS。当PTS不一致时我们需要将PTS统一,可以直接统一到从0开始计数。ffmpeg -i original.mp4 -i encoded.mp4 -lavfi "[0:v]scale=1024:576,setpts=PTS-STARTPTS[origin];[1:v]setpts=PTS-STARTPTS[encoded];[origin][encoded]libvmaf=model_path=../model/vmaf_v0.6.1.json:log_fmt=xml:log_path=/dev/stdout" -f null -当视频时间不一致时
如果要测试的两个视频时长不一致,那么我们需要指定以短视频为准,短视频处理完毕,则整个计算结束。需要用到的参数是shortest和repeatlast。ffmpeg -i original.mp4 -i encoded.mp4 -lavfi "[0:v]scale=1024:576,setpts=PTS-STARTPTS[origin];[1:v]setpts=PTS-STARTPTS[encoded];[origin][encoded]libvmaf=model_path=../model/vmaf_v0.6.1.json:log_fmt=xml:log_path=/dev/stdout:shortest=1:repeatlast=0" -f null -shortest:
默认值是0,即为当短视频处理结束后,不会停止,这里设置为1;
repeatlast:
默认值是1,即直到较长的视频结束前,较短的视频会一直反复处理,这里设置为0。
4.5. VMAF执行结果
vmaf最终结果是一个0~100之间的数字,越大越好。通常情况下,我们认为95分以上基本没有差异,93~95分能感知到差异但可接受,91分以下通常差异比较明显。
你会遇到一种情况就是整体看视频觉得效果还行,但评分却很低。如果你执行的是上面的命令,那么请查看一下log,你会发现里面包含了每一帧计算的结果,比如第0帧:
<frame frameNum="0" integer_adm2="0.992588" integer_adm_scale0="0.974760" integer_adm_scale1="0.985340" integer_adm_scale2="0.994697" integer_adm_scale3="0.998173" integer_motion2="0.000000" integer_motion="0.000000" integer_vif_scale0="0.795167" integer_vif_scale1="0.978604" integer_vif_scale2="0.991164" integer_vif_scale3="0.995545" vmaf="94.955235" />
然后请找一下vmaf值比较低的帧,利用ffmpeg取出编码后视频和原视频的对应帧,再做对比,能发现比较明显的差异。
原视频某帧:

编码后同一帧:

随着人们对视频质量的愈加关注,vmaf的使用也越来越多,并且相较于其他指标,vmaf的结果更加贴近人的真实感受,同时又是标准统一的量化值,有助于发现视频编码过程中的问题并加以改进。本文主要着眼于vmaf工具在ffmpeg上的使用,逐一列举要注意的点,并解释常用参数的含义和配置,希望对正准备使用vmaf的小伙伴有一定帮助。
【参考文献】
《libvmaf》(https://github.com/Netflix/vmaf/blob/master/libvmaf/README.md)
《Using VMAF with FFmpeg》(https://github.com/Netflix/vmaf/blob/master/resource/doc/ffmpeg.md)
《新しい映像の品質評価 LIBVMAF》(https://nico-lab.net/libvmaf_with_ffmpeg/)
《ffmpeg命令详解(转)》(https://www.cnblogs.com/AllenChou/p/7048528.html)
《使用VMAF对视频质量进行分析》(https://roov.org/2020/08/vmaf/)
《VMAF in FFmpeg – Installation and Usage Guide for Ubuntu》(https://ottverse.com/vmaf-ffmpeg-ubuntu-compilation-installation-usage-guide/)




