ffmpeg - FFMPEG Hwaccel错误与hwupload

标签 ffmpeg hardware-acceleration vaapi

我目前正在尝试在FFMPEG上使用vaapi hwaccelleration。

在我的命令中,我在hwaccel上具有vaapi,在hwaccel_output_fomrat上具有vaapi,在-hwaccel_device上具有/dev/dri/renderD128,并且在-vf上具有format=nv12, hwupload,在-c:v和视频编解码器h264_vaapi >。

现在尝试启动它时,出现错误

grep stderr: [hwupload @ 0x30bb660] A hardware deveice reference is required to upload frames to. [Parsed_hwupload_1 @ 0x30bb560] Query format failed for 'Parsed_hwupload_1': Invalid argument

我可以在某处定义硬件设备参考吗?我以为这是我对hwaccel_device的处理,但似乎没有。那么我该怎么做才能使它正常工作呢?

最佳答案

您需要正确初始化硬件加速器,如下面的文档所示(也许我们应该为此及时创建一个Wiki条目?):

假定以下代码段:

ffmpeg -re -threads 4 -loglevel debug \
-init_hw_device vaapi=intel:/dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device intel -filter_hw_device intel \
-i 'udp://$ingest_ip:$ingest_port?fifo_size=9000000' \
-vf 'format=nv12|vaapi,hwupload' \
-c:v h264_vaapi -b:v $video_bitrate$unit -maxrate:v $video_bitrate$unit -qp:v 21 -sei +identifier+timing+recovery_point -profile:v main -level 4 \
-c:a aac -b:a $audio_bitrate$unit -ar 48000 -ac 2 \
-flags -global_header -fflags +genpts -f mpegts 'udp://$feed_ip:$feed_port'


哪里:

(一个)。 VAAPI可用,我们将DRM节点/dev/dri/renderD128绑定到编码会话,并且

(b)。我们采用udp输入,其中$ingest_ip:$port_ip对应于已知的UDP输入流,分别与IP和端口配对匹配,并具有定义的fifo大小(如'?fifo_size=n'参数所示)。

(C)。编码为打包为MPEG传输流的输出udp流(请参见使用的多路复用器,mpegts),其必要参数分别与输出IP和端口对匹配。

(d)。定义的视频比特率($video_bitrate$unit,其中$ unit可以为K或M,如您所见)和音频比特率($audio_bitrate$unit,其中$ unit为K,对于基于AAC LC的编码),如上所示,并将适当的编码器设置传递给vaapi编码器。供您参考,在撰写本文时,FFmpeg中有四个可用的视频编码器,分别是:

i. h264_vaapi

ii. hevc_vaapi

iii. vp8_vaapi

iii. vp9_vaapi


由于省略了mj​​peg编码器(在此上下文中它不感兴趣),因此可以通过以下方式访问每个编码器的文档:

ffmpeg -hide_banner -h encoder=$encoder_name


其中$encoder_name与上面列表中的编码器匹配。

对于VAAPI,适用以下注意事项:


基于VAAPI的编码器只能将输入作为VAAPI曲面,因此通常需要hwupload实例先将其转换为vaapi格式的帧。请注意,表面的内部格式将从hwupload输入的格式派生,因此可能需要其他格式过滤器才能使一切正常工作,如上面的代码片段所示:


一世。 -init_hw_device vaapi=intel:/dev/dri/renderD128初始化绑定到DRM渲染节点-hwaccel_device的名为vaapi的硬件设备(稍后可以通过-filter_hw_device/dev/dri/renderD128调用)。可以删除intel:前缀,但它通常用于识别存在多个VAAPI功能的设备(例如具有Intel IGP和AMD GPU的装备)的环境中供应商名称使用的渲染节点。

ii。注意-hwaccel_output_format vaapi定义的格式约束。满足1中的条件是必需的。

iii。然后,我们选择命名的硬件加速实现vaapi,并为硬件加速器设备(-hwaccel_device)和将通过hwupload筛选器(-filter_hw_device)将硬件帧上传到的设备调用它。如您所见,省略后者将导致编码器初始化失败。

iv。现在,仔细检查视频过滤器语法:

-vf 'format=nv12|vaapi,hwupload'


该视频过滤器链将任何不受支持的视频帧转换为VAAPI硬件格式,并在通过hwupload将帧上传到设备之前应用已知的约束。这样做是出于安全原因;您不能假设解码格式将被编码器接受。此模式下的性能会根据使用的源,解码器设备和VAAPI驱动程序而有所不同。

v。现在,对于视频编码器(由-c:v $encoder_name定义),根据需要传递您的参数。您可以修改我在上面的代码段中提供的示例,但是如果需要进一步的调整,可以参考前面解释的编码器文档,这是明智的选择。

奖励:处理基于Intel的QSV编码器:

对于那些使用FFmpeg的QSV支持的Intel开源MSDK和相关编码器的用户,我将提供本节以供将来参考。请参见下面的代码段:

ffmpeg -re -threads 4 -loglevel debug \
-init_hw_device qsv=qsv:MFX_IMPL_hw_any -hwaccel qsv -filter_hw_device qsv \
-i 'udp://$ingest_ip:$ingest_port?fifo_size=9000000' \
-vf 'hwupload=extra_hw_frames=10,vpp_qsv:deinterlace=2,format=nv12' \
-c:v h264_qsv -b:v $video_bitrate$unit -rdo 1 -pic_timing_sei 1 -recovery_point_sei 1 -profile high -aud 1 \
-c:a aac -b:a $audio_bitrate$unit -ar 48000 -ac 2 \
-flags -global_header -fflags +genpts -f mpegts 'udp://$feed_ip:$feed_port'


您可以看到相似之处。

QSV编码器使用VAAPI样式的映射(如上所述),但对hwupload过滤器施加了额外的约束:必须使用hwupload=extra_hw_frames=10参数,否则编码器的初始化将失败。

尽管QSV编码器据说输出质量更好,但我仍然不能推荐它们的原因之一是它们的脆弱映射,它们通常会退出一些最无用的错误,这些错误通常与编码器的故障无关。
如果可能,请坚持使用VAAPI。 QSV的有用性(如适用)适用于低功耗编码,就像Intel的Apollolake和anemic Cannonlake initial offerings一样。

希望本文档对您有用。

关于ffmpeg - FFMPEG Hwaccel错误与hwupload,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45476554/

相关文章:

ffmpeg - 添加 GIF 作为水印和循环 FFMPEG

java - 具有两个 GPU 的笔记本电脑上的硬件加速 BufferedImage

android - LAYER_TYPE_SOFTWARE 在一段时间内不会在某些设备上禁用硬件加速

ffmpeg - 使用 ffmpeg 和 vaapi 对 HEVC 4K HDR 进行转码

video - FFMPEG 硬件编码 H264

ffmpeg 将具有 8 个音频 channel 的视频文件转换为多 channel wav

opengl - ffmpeg 和 opengl

php - FFMPEG 安装 php.ini有人知道有什么好的指南吗?

html - Webkit 硬件加速渗入页面上的其他元素?

docker - Docker Swarm通用设备资源连接