Intel i5 Kaby Lake 硬件辅助使用 ffmpeg 将视频和音频转码为 VP9 和 FLAC

Intel i5 Kaby Lake 硬件辅助使用 ffmpeg 将视频和音频转码为 VP9 和 FLAC

我有大约 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 进行编码。所以我有两个问题:

  1. 我的朋友可以使用哪些ffmpeg参数将视频转码为 VP9,将音频转码为 MKV 容器中的 FLAC?它们可以在 Windows 上使用吗?如果不行,那也没关系,因为他有 Windows 10-Linux 双启动。

  2. 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 placebox264 但更差)但质量较高,而 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 测试平台运行这些编码测试并报告结果 :-)

相关内容