【问题标题】:FFMPEG Hwaccel error with hwuploadFFMPEG Hwaccel 错误与 hwupload
【发布时间】:2017-08-03 06:32:54
【问题描述】:

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

在我的命令中,我在vaapi 上有hwaccel,在vaapi 上有hwaccel_output_fomrat,在/dev/dri/renderD128 上有-hwaccel_device,还有-vf 作为format=nv12, hwupload 和视频编解码器-c:vh264_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 所做的,但似乎不是。那么我该怎么做才能让它发挥作用呢?

【问题讨论】:

    标签: ffmpeg hardware-acceleration vaapi


    【解决方案1】:

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

    假设以下 sn-p:

    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
    

    省略了 mjpeg 编码器(因为它在此上下文中不感兴趣),并且每个编码器的文档都可以通过以下方式访问:

    ffmpeg -hide_banner -h encoder=$encoder_name
    

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

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

    1. 基于 VAAPI 的编码器只能将输入作为 VAAPI 表面,因此它通常需要先于 hwupload 实例才能将普通帧转换为 vaapi 格式帧。请注意,表面的内部格式将源自 hwupload 输入的格式,因此可能需要额外的格式过滤器才能使一切正常,如上面的 sn-p 所示:

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

    二。注意-hwaccel_output_format vaapi 定义的格式约束。这需要满足1中的条件。

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

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

    -vf 'format=nv12|vaapi,hwupload'
    

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

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

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

    我将本节包括在内以供将来参考,供那些使用英特尔开源 MSDK 以实现 FFmpeg 的 QSV 启用和相关编码器的人。请参阅下面的 sn-p:

    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

    希望本文档对您有用。

    【讨论】:

      猜你喜欢
      • 2019-08-31
      • 1970-01-01
      • 2011-08-24
      • 2021-06-04
      • 2020-06-17
      • 1970-01-01
      • 2011-02-16
      • 1970-01-01
      • 2016-01-22
      相关资源
      最近更新 更多