如何使用 ffmpeg 和 vp9_qsv 编码 VP9 视频?

如何使用 ffmpeg 和 vp9_qsv 编码 VP9 视频?

我正在尝试使用 ffmpeg 在 Windows 10 上使用 vp9_qsv(英特尔快速同步视频硬件支持)对 VP9 视频进行编码。我之前曾使用 libvpx-vp9 成功编码过 VP9 视频,但这样会占用大量 CPU,而且速度相当慢。现在我尝试切换到 vp9_sqv,但收到一些不太有用的错误消息,文档也相当缺乏。

ffmpeg.exe -i input.mp4 -c:v vp9_qsv -c:a copy output.webm

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.20.100
  Duration: 00:00:46.74, start: 0.040000, bitrate: 15752 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 15561 kb/s, 25.02 fps, 25 tbr, 12800 tbn, 50 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 193 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> vp9 (vp9_qsv))
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[vp9_qsv @ 000001b156147b40] Selected ratecontrol mode is unsupported
[vp9_qsv @ 000001b156147b40] Low power mode is unsupported
[vp9_qsv @ 000001b156147b40] Current frame rate is unsupported
[vp9_qsv @ 000001b156147b40] Current picture structure is unsupported
[vp9_qsv @ 000001b156147b40] Current resolution is unsupported
[vp9_qsv @ 000001b156147b40] Current pixel format is unsupported
[vp9_qsv @ 000001b156147b40] some encoding parameters are not supported by the QSV runtime. Please double check the input parameters.
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
Conversion failed!

我尝试指定它要求的一些内容,但产生了完全相同的错误。

ffmpeg.exe -i input.mp4 -c:v vp9_qsv -preset veryslow -low_power 0 -b:v 800K -c:a copy output.webm

编辑:根据 Mokubai 的建议,我现在得到以下信息: ffmpeg.exe -init_hw_device qsv=hw -filter_hw_device hw -f rawvideo -pix_fmt yuv420p -s:v 1920x1080 -i input.mp4 -vf hwupload=extra_hw_frames=64,format=qsv -c:v vp9_qsv -c:a copy output.webm

[AVHWDeviceContext @ 000001d30eccb640] Error setting child device handle: -6

答案1

首先,值得一提的是,英特尔在 Tiger Lake CPU 之前尚未在其 Quicksync 编码器中正式启用 VP9 支持。一些迹象表明可能能够在 Linux 中工作在 Kaby Lake(第 7 代)处理器上以及更高版本上有一些混乱,但有一位用户对英特尔媒体驱动程序状态

抱歉回复迟了,我们不会在 Gen9 平台上启用 VP9 编码,如果有人仍然想要,可以尝试 PR #717,它添加了 VP9 编码支持。但是 Gen9 VME 设计并未针对 VP9 进行优化。所以我们对此有所担忧。

Gen9 是 Tiger Lake 之前的大量平台,其本身使用 Gen 11 显卡。

这就是说 QSV 示例部分FFMPEG wiki:硬件 / QuickSync 似乎建议您可以在初始化硬件-init_hw_device qsv=hw -filter_hw_device hw -f rawvideo -pix_fmt yuv420p -s:v 1920x1080之前添加(假设是YUV420源)。-i input.mp4

然后使用-vf hwupload=extra_hw_frames=64,format=qsv之前-c:v指定编码器想要的格式,尽管我没有可以测试的功能硬件。

至少 FFMPEG wiki 确实有一些希望,但即使在 Tiger Lake CPU 上,我也无法让它转码任何视频。无论我怎么尝试,我都会得到以下几行

[swscaler @ 000001c902edec40] deprecated pixel format used, make sure you did set range correctly
[vp9_qsv @ 000001c97dc7ef40] Selected ratecontrol mode is unsupported
[vp9_qsv @ 000001c97dc7ef40] some encoding parameters are not supported by the QSV runtime. Please double check the input parameters.
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
Conversion failed!

我可以愉快地使用 h264_qvc 编码器,但切换到 vp9_qvc 会引发错误,并且我找不到有关如何指定必要的任何提示ratecontrol

我的示例命令行有效

.\ffmpeg.exe -init_hw_device qsv=hw -i 'MVI_7664.mov' -vf hwupload=extra_hw_frames=64,format=qsv -c:v h264_qsv -strict experiments -preset veryslow -c:a copy output.mkv -y

但它使用的是 h264 而不是 VP9。也许我需要更新的 FFMPEG。

答案2

使用英特尔的 QuickSync(在支持的平台上):

这个答案扩展了上面的答案,并做了一些更改:

  1. 对于vp9_qsv编码器包装器,请注意低功耗模式是强制性的(目前)。如果未能设置该模式(通过私有编解码器选项-low_power 1)将导致失败,此时 MFX 运行时将打印出类似以下内容的日志:
[vp9_qsv @ 000001b156147b40] Selected ratecontrol mode is unsupported
[vp9_qsv @ 000001b156147b40] Low power mode is unsupported
[vp9_qsv @ 000001b156147b40] Current frame rate is unsupported
[vp9_qsv @ 000001b156147b40] Current picture structure is unsupported
[vp9_qsv @ 000001b156147b40] Current resolution is unsupported
[vp9_qsv @ 000001b156147b40] Current pixel format is unsupported
[vp9_qsv @ 000001b156147b40] some encoding parameters are not supported by the QSV runtime. Please double check the input parameters.
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
Conversion failed!

这是因为 QSV MFX 运行时必须与设备驱动程序协商所有要求(iHD在 Linux 上)MFX 会话可以成功注册。据我所知,此包装器目前仅适用于 Linux。这可能会在不久的将来发生变化。

  1. 以下所有示例均展示 1:N 转码的情况(即,一个输入用于提供多个输出)。还使用了复杂的过滤器链,以及tee调用底层segment复用器的复用器从属。

在 Intel Icelake 及更高版本上,您可以使用vp9_qsv编码器包装器,但存在以下已知限制(目前),如在 Linux 上测试的那样:

(a). 您必须启用,因为目前驱动程序low_power mode仅公开了 VDENC 解码路径。iHD

(b).MSDK不支持编码选项1和extra_data。

(c). MSDK 中会默认插入 IVF 头,但 FFmpeg 不需要该头,因此默认为禁用状态。

请参阅下面的示例,通过tee调用segment多路复用器的多路复用器从属设备获取单个输入并产生多个输出:

  1. 如果需要去隔行,请vpp_qsv按如下所示调用过滤器:
    ffmpeg -nostdin -y -fflags +genpts \
    -init_hw_device vaapi=va:/dev/dri/renderD128,driver=iHD \
    -filter_hw_device va -hwaccel vaapi -hwaccel_output_format vaapi \
    -threads 4 -vsync 1 -async 1 \
    -i 'http://server:port' \
    -filter_complex "[0:v]hwmap=derive_device=qsv,format=qsv,vpp_qsv=deinterlace=2:async_depth=4,split[n0][n1][n2]; \
    [n0]vpp_qsv=w=1152:h=648:async_depth=4[v0]; \
    [n1]vpp_qsv=w=848:h=480:async_depth=4[v1];
    [n2]vpp_qsv=w=640:h=360:async_depth=4[v2]" \
    -b:v:0 2250k -maxrate:v:0 2250k -bufsize:v:0 360k -c:v:0 vp9_qsv -g:v:0 50 -r:v:0 25 -low_power:v:0 2 \
    -b:v:1 1750k -maxrate:v:1 1750k -bufsize:v:1 280k -c:v:1 vp9_qsv -g:v:1 50 -r:v:1 25 -low_power:v:1 2 \
    -b:v:2 1000k -maxrate:v:2 1000k -bufsize:v:2 160k -c:v:2 vp9_qsv -g:v:2 50 -r:v:2 25 -low_power:v:2 2 \
    -c:a aac -b:a 128k -ar 48000 -ac 2 \
    -flags -global_header -f tee -use_fifo 1 \
    -map "[v0]" -map "[v1]" -map "[v2]" -map 0:a \
    "[select=\'v:0,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path0/output%03d.mp4| \
     [select=\'v:1,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path1/output%03d.mp4| \
     [select=\'v:2,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path2/output%03d.mp4"
  1. 不使用去隔行:
    ffmpeg -nostdin -y -fflags +genpts \
    -init_hw_device vaapi=va:/dev/dri/renderD128,driver=iHD \
    -filter_hw_device va -hwaccel vaapi -hwaccel_output_format vaapi \
    -threads 4 -vsync 1 -async 1 \
    -i 'http://server:port' \
    -filter_complex "[0:v]hwmap=derive_device=qsv,format=qsv,split=3[n0][n1][n2]; \
    [n0]vpp_qsv=w=1152:h=648:async_depth=4[v0]; \
    [n1]vpp_qsv=w=848:h=480:async_depth=4[v1];
    [n2]vpp_qsv=w=640:h=360:async_depth=4[v2]" \
    -b:v:0 2250k -maxrate:v:0 2250k -bufsize:v:0 2250k -c:v:0 vp9_qsv -g:v:0 50 -r:v:0 25 -low_power:v:0 2  \
    -b:v:1 1750k -maxrate:v:1 1750k -bufsize:v:1 1750k -c:v:1 vp9_qsv -g:v:1 50 -r:v:1 25 -low_power:v:1 2  \
    -b:v:2 1000k -maxrate:v:2 1000k -bufsize:v:2 1000k -c:v:2 vp9_qsv -g:v:2 50 -r:v:2 25 -low_power:v:2 2  \
    -c:a aac -b:a 128k -ar 48000 -ac 2 \
    -flags -global_header -f tee -use_fifo 1 \
    -map "[v0]" -map "[v1]" -map "[v2]" -map 0:a \
    "[select=\'v:0,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path0/output%03d.mp4| \
     [select=\'v:1,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path1/output%03d.mp4| \
     [select=\'v:2,a\':f=segment:segment_time=5:segment_format_options=movflags=+faststart]$output_path2/output%03d.mp4"

请注意,我们使用了vpp_qsv filter选项设置为 4 的。与使用和async_depth相比,这大大提高了转码性能。请参阅scale_qsvdeinterlace_qsv这次提交在 FFmpeg 的 git 上。

笔记:

这只适用于运行当前media-driverVAAPI H/W 加速包的 Linux,ffmpeg 通过-init_hw_device vaapi=va:/dev/dri/renderD128,driver=iHD -filter_hw_device va -hwaccel vaapi -hwaccel_output_format vaapi绑定到 DRI 节点来选择/dev/dri/rendereD128它。这是单 GPU 系统上的默认设置。但是,如果存在多个 GPU,情况将会改变。我们使用 VAAPI 进行 H/W 加速,因为它对解码加速更具弹性。QuickSync 解码非常脆弱,会导致多个输入文件出现 MFX 错误。

我们还通过hwmap过滤器派生出一个 QSV 上下文,通过该上下文调用,hwmap=derive_device=qsv,format=qsv然后立即链接到format=qsv过滤器,指定我们希望 QSV H/W 帧被馈送到vpp_qsv复杂过滤器链中的相邻过滤器。

警告:

  1. 使用 QuickSync 时,无论使用何种输入格式和 QSV 编码器包装器,CPU 开销都会略高,尤其是在较小的处理器上,例如Intel Atom® x7-E3950 Processor。与功能更强大的台式机级处理器和支持 Iris Pro 的 CPU 相比,相同的开销会大大减轻。
  2. 对于基于 VP9 的硬件编码,我仍然强烈建议使用vp9_vaapi编码器包装器,并且但有警告(与 B 帧和速率控制模式的使用有关)。VAAPI 总体上比 QSV 更稳定。

参考:

  1. 查看编码器选项,包括支持的速率控制方法:
ffmpeg -h encoder=vp9_qsv
  1. 关于vpp_qsv过滤器的使用,请参见:
ffmpeg -h filter=vpp_qsv

警告:

请注意,SDK 至少需要 2 个线程来防止死锁,请参阅代码块。

相关内容