FFMPEG Hwaccel错误与hwupload

时间:2017-08-03 06:32:54

标签: ffmpeg hardware-acceleration vaapi

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

在我的命令中,我<div style="background-color:blue"> <!-- color not working --> <span style="background-color:red"><H2>boo-title</H2> <!-- color working --> <script language="JavaScript"> document.write("boo"); </script> </span> <span style="background-color:green"><H2>foo-title</H2> <!-- color working --> <script language="JavaScript"> document.write("foo"); </script> </span> </div> hwaccelvaapihwaccel_output_fomratvaapi-hwaccel_device以及{{{} 1}} /dev/dri/renderD128-vf上的视频编解码器format=nv12, hwupload

当我现在尝试启动它时,我收到了错误

-c:v

我可以在某处定义硬件设备参考吗?我认为这是我对h264_vaapi所做的,但似乎不是。那么我该怎么做才能让它发挥作用呢?

1 个答案:

答案 0 :(得分:2)

您需要正确初始化硬件加速器,如下面的文档所示(也许我们应该及时为此创建一个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'

其中:

(a)中。 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,以下注释适用:

  1. 基于VAAPI的编码器只能将输入作为VAAPI表面,因此通常需要在hwupload实例之前将普通帧转换为vaapi格式帧。请注意,曲面的内部格式将从hwupload输入的格式派生,因此可能需要其他格式过滤器才能使一切正常工作,如上面的代码段所示:
  2. 我。 -init_hw_device vaapi=intel:/dev/dri/renderD128初始化名为vaapi的硬件设备(稍后可通过-hwaccel_device-filter_hw_device调用,如上所示)绑定到DRM渲染节点/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驱动程序而有所不同。

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

    奖励:处理基于英特尔的QSV编码器:

    我将此部分包括在内以供将来参考,因为这些人使用英特尔的开源MSDK来实现FFmpeg的QSV和相关的编码器。请参阅下面的代码:

    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的有用性(适用时)适用于低功耗编码,就像英特尔的Apollolake和anemic Cannonlake initial offerings一样。

    希望此文档对您有用。