我正在尝试使用 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(在支持的平台上):
这个答案扩展了上面的答案,并做了一些更改:
- 对于
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: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
多路复用器的多路复用器从属设备获取单个输入并产生多个输出:
- 如果需要去隔行,请
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"
- 不使用去隔行:
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_qsv
deinterlace_qsv
这次提交在 FFmpeg 的 git 上。
笔记:
这只适用于运行当前media-driver
VAAPI 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
复杂过滤器链中的相邻过滤器。
警告:
- 使用 QuickSync 时,无论使用何种输入格式和 QSV 编码器包装器,CPU 开销都会略高,尤其是在较小的处理器上,例如
Intel Atom® x7-E3950 Processor
。与功能更强大的台式机级处理器和支持 Iris Pro 的 CPU 相比,相同的开销会大大减轻。 - 对于基于 VP9 的硬件编码,我仍然强烈建议使用
vp9_vaapi
编码器包装器,并且但有警告(与 B 帧和速率控制模式的使用有关)。VAAPI 总体上比 QSV 更稳定。
参考:
- 查看编码器选项,包括支持的速率控制方法:
ffmpeg -h encoder=vp9_qsv
- 关于
vpp_qsv
过滤器的使用,请参见:
ffmpeg -h filter=vpp_qsv
警告:
请注意,SDK 至少需要 2 个线程来防止死锁,请参阅这代码块。