我有大约 30 GB 的视频(大部分是 MP4,一些是 MKV 和 webm),需要将其从各种输入编解码器(AAC 音频;H264、VP8、H265/HEVC,可能还有一些其他视频编解码器)转码为 8 位 VP9,并在 MKV 容器中使用免费无损音频编解码器 (FLAC) 音频。在我最强大的系统上,转码低分辨率视频所需的时间是视频长度的两倍。我ffmpeg
在 Linux 上使用参数ffmpeg -i input -c:v libvpx-vp9 -lossless 1 -c:a FLAC -preset veryslow output.mkv
来转码视频,而无需硬件帮助。然而,最近,我的一个朋友为他的 PC 买了一个 Intel i5 Kaby Lake CPU,并提出帮我转码视频。根据维基百科及其参考新的 Kaby Lake CPU 支持对我的所有输入编解码器进行硬件解码和对 8 位 VP9 进行编码。所以我有两个问题:
我的朋友可以使用哪些
ffmpeg
参数将视频转码为 VP9,将音频转码为 MKV 容器中的 FLAC?它们可以在 Windows 上使用吗?如果不行,那也没关系,因为他有 Windows 10-Linux 双启动。veryslow
为了获得最佳压缩是否仍然需要预设?
我曾尝试在其他地方找到该问题的答案,但只能找到 H264 和 JPEG 等编码编解码器的示例。
答案1
2017 年 8 月 3 日更新:根据用户林正浩的最新回答,ffmpeg 现在支持通过 VAAPI 进行 VP9 编码。不过,我还没有测试所需的硬件,所以我的回答帮助有限。我将在下面留下关于如何在软件中编码 VP9 的原始回答。
由于某种原因,FFmpeg 不支持英特尔 QuickSync 硬件编码器上的 VP9 编码,即使它们支持 H.264 和 HEVC。通过搜索 FFmpeg 源代码存储库显示,这根本不是禁用的问题,只是该功能尚未实现。但如果将来某个时候确实可用,它应该可以以与其他 QuickSync 编码器类似的方式使用:使用 而不是 的开关-c:v vp9_qsv
应该-c:v libvpx-vp9
可以完成工作。
FFmpeg 命令行用法在所有平台上都是相同的,但据我所知,有一个值得注意的例外,即 Windows 用户在 2 遍编码的第一遍期间必须使用NUL
而不是/dev/null
进行输出。但由于您正在进行 1 遍和无损编码,因此这不会对您造成影响。
如果您想加快编码速度,最明显的做法是使用开关设置编码速度值-speed
。推荐值是从 0 到 4 的数字,其中 0 表示非常非常慢(想想-preset placebo
x264 但更差)但质量较高,而 4 表示速度快但质量较低。ffmpeg-speed 1
默认使用,这对于有损编码来说是一个很好的速度与质量权衡。但是,我刚刚使用不同的速度值进行了快速无损编码测试,并注意到从 到-speed 1
无损-speed 0
编码后文件大小减少了 32%。但是编码时间增加了两倍,所以是否值得使用 取决于您。生成的文件-speed 4
仅比生成的文件大 1.1% -speed 1
,编码速度提高了 43%。所以我想说如果你正在进行无损并且-speed 0
速度太慢,你不妨使用-speed 4
。
另一个重要的编码性能提升是使用开关打开多线程-threads
;libvpx 不会自动使用多线程,因此必须由用户手动设置。您还应该使用开关设置图块列的数量-tile-columns
。此选项使 libvpx 将视频分成多个图块并并行编码这些图块以实现更好的多线程。您可以在“平铺和线程建议”部分中找到图块列和线程数量的建议数字Google 的 VP9 编码指南。如您所见,使用的线程数会随着图块数量的增加而增加,这意味着根据可用的 CPU 核心数量,您的处理器在编码亚高清分辨率视频时可能不会完全饱和。如果您主要编码低分辨率视频,您可能需要考虑同时编码多个文件。
然而,完后还有加速 VP9 编码的方法:在单个列图块内使用多线程,可以通过 启用-row mt 1
。截至 4 月 4 日(2017 年,未来的人们,你好),它不是 libvpx 发行版本的一部分,但很可能在 libvpx 1.6.2 中。如果您想在下一个版本之前试用它,您需要从源代码编译 libvpx 和 ffmpeg 的最新 git 版本。只需按照FFmpeg 的编译指南对于您选择的发行版,但不要下载并提取发布 tarball,git pull https://chromium.googlesource.com/webm/libvpx
而是这样做。
至于veryslow
预设,它仅在 x264 和 x265 中使用。libvpx 使用开关-speed
以及-quality best
、-quality good
或-quality realtime
选项来定义编码器编码一帧所用的时间。默认值是-quality good
因为-quality best
速度太慢而无法使用,因此-quality realtime
适用于视频通话和直播等时间紧迫的应用程序。
答案2
截至今天,可以使用 VAAPI 构建 FFmpeg,在支持的系统上,它允许您在 Intel 集成 GPU 上编码 VP9。
新的编码器,当 ffmpeg使用 VAAPI 支持进行编译, 叫做vp9_vaapi
。
要查看调整编码器时可用的选项,请运行:
ffmpeg -hide-banner -h encoder=vp9_vaapi
输出:
Encoder vp9_vaapi [VP9 (VAAPI)]:
General capabilities: delay
Threading capabilities: none
Supported pixel formats: vaapi_vld
vp9_vaapi AVOptions:
-loop_filter_level <int> E..V.... Loop filter level (from 0 to 63) (default 16)
-loop_filter_sharpness <int> E..V.... Loop filter sharpness (from 0 to 15) (default 4)
当你尝试在 Skylake 等不受支持的硬件上实现此功能时会发生什么?
请参阅下面的示例输出:
[Parsed_format_0 @ 0x42cb500] compat: called with args=[nv12]
[Parsed_format_0 @ 0x42cb500] Setting 'pix_fmts' to value 'nv12'
[Parsed_scale_vaapi_2 @ 0x42cc300] Setting 'w' to value '1920'
[Parsed_scale_vaapi_2 @ 0x42cc300] Setting 'h' to value '1080'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'video_size' to value '3840x2026'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'pix_fmt' to value '0'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'time_base' to value '1/1000'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'pixel_aspect' to value '1/1'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'sws_param' to value 'flags=2'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'frame_rate' to value '24000/1001'
[graph 0 input from stream 0:0 @ 0x42cce00] w:3840 h:2026 pixfmt:yuv420p tb:1/1000 fr:24000/1001 sar:1/1 sws_param:flags=2
[format @ 0x42cba40] compat: called with args=[vaapi_vld]
[format @ 0x42cba40] Setting 'pix_fmts' to value 'vaapi_vld'
[auto_scaler_0 @ 0x42cd580] Setting 'flags' to value 'bicubic'
[auto_scaler_0 @ 0x42cd580] w:iw h:ih flags:'bicubic' interl:0
[Parsed_format_0 @ 0x42cb500] auto-inserting filter 'auto_scaler_0' between the filter 'graph 0 input from stream 0:0' and the filter 'Parsed_format_0'
[AVFilterGraph @ 0x42ca360] query_formats: 6 queried, 4 merged, 1 already done, 0 delayed
[auto_scaler_0 @ 0x42cd580] w:3840 h:2026 fmt:yuv420p sar:1/1 -> w:3840 h:2026 fmt:nv12 sar:1/1 flags:0x4
[hwupload @ 0x42cbcc0] Surface format is nv12.
[AVHWFramesContext @ 0x42ccbc0] Created surface 0x4000000.
[AVHWFramesContext @ 0x42ccbc0] Direct mapping possible.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000001.
[AVHWFramesContext @ 0x42c3e40] Direct mapping possible.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000002.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000003.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000004.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000005.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000006.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000007.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000008.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000009.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x400000a.
[vp9_vaapi @ 0x409da40] Encoding entrypoint not found (19 / 6).
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
[AVIOContext @ 0x40fdac0] Statistics: 0 seeks, 0 writeouts
[aac @ 0x40fcb00] Qavg: -nan
[AVIOContext @ 0x409f820] Statistics: 32768 bytes read, 0 seeks
Conversion failed!
有趣的是,该特定平台上不存在针对 VP9 编码的入口点警告,这由 vainfo 的输出确认:
libva info: VA-API version 0.40.0
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/local/lib/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_40
libva info: va_openDriver() returns 0
vainfo: VA-API version: 0.40 (libva 1.7.3)
vainfo: Driver version: Intel i965 driver for Intel(R) Skylake - 1.8.4.pre1 (glk-alpha-71-gc3110dc)
vainfo: Supported profile and entrypoints
VAProfileMPEG2Simple : VAEntrypointVLD
VAProfileMPEG2Simple : VAEntrypointEncSlice
VAProfileMPEG2Main : VAEntrypointVLD
VAProfileMPEG2Main : VAEntrypointEncSlice
VAProfileH264ConstrainedBaseline: VAEntrypointVLD
VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
VAProfileH264Main : VAEntrypointVLD
VAProfileH264Main : VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointEncSliceLP
VAProfileH264High : VAEntrypointVLD
VAProfileH264High : VAEntrypointEncSlice
VAProfileH264High : VAEntrypointEncSliceLP
VAProfileH264MultiviewHigh : VAEntrypointVLD
VAProfileH264MultiviewHigh : VAEntrypointEncSlice
VAProfileH264StereoHigh : VAEntrypointVLD
VAProfileH264StereoHigh : VAEntrypointEncSlice
VAProfileVC1Simple : VAEntrypointVLD
VAProfileVC1Main : VAEntrypointVLD
VAProfileVC1Advanced : VAEntrypointVLD
VAProfileNone : VAEntrypointVideoProc
VAProfileJPEGBaseline : VAEntrypointVLD
VAProfileJPEGBaseline : VAEntrypointEncPicture
VAProfileVP8Version0_3 : VAEntrypointVLD
VAProfileVP8Version0_3 : VAEntrypointEncSlice
VAProfileHEVCMain : VAEntrypointVLD
VAProfileHEVCMain : VAEntrypointEncSlice
VAProfileVP9Profile0 : VAEntrypointVLD
VP9 配置文件 0 的 VLD(可变长度解码)入口点是 Skylake 在 VP9 硬件加速方面达到的最远的。
使用 Kabylake 测试平台运行这些编码测试并报告结果 :-)