且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用GPU加快ffmpeg过滤器的处理速度?

更新时间:2023-01-31 09:13:48

关于FFmpeg中的硬件加速,您可以期望按类型实现以下实现:

1.硬件加速编码器::对于NVIDIA,通过h264_nvenc和hevc_nvenc包装器支持和实现NVENC.请参阅答案,了解如何对其进行调整以及任何限制您可能会遇到这种情况,具体取决于您所使用的硬件的一代.

2.硬件加速的过滤器:执行职责的过滤器,例如缩放和后期处理(去隔行等)在FFmpeg中可用,并且某些实现是硬件加速的.对于NVIDIA,以下过滤器可以利用硬件加速功能:

(a). scale_cuda :这是类似于CUDA中实现的通用比例过滤器的比例过滤器.它的依赖项是 ffnvcodec 项目,还需要标头来启用基于NVENC的编码器.如果存在ffnvcodec标头,则取决于它的各个过滤器(scale_cuda和yadif_cuda)将自动启用.在生产中,***弃用此过滤器,而推荐使用scale_npp,因为它的选项集非常有限.

(b). scale_npp :这是在 CUDA SDK ,必须通过传递--enable-libnpp明确启用它,从源代码构建FFmpeg时,在编译时将--enable-cuda-nvcc--enable-nonfree标志标记为./configure.尽可能使用此过滤器代替scale_cuda.

(c). yadif_cuda :这是一种去隔行器,在CUDA中实现.如上所述,它的依赖项是ffnvcodec标头包.

(d). 所有基于OpenCL的过滤器:主线NVIDIA驱动程序和CUDA SDK都支持的所有支持NVENC的GPU均实现OpenCL支持.我从澄清这一节开始,因为风中有消息称NVIDIA将 Wiki部分以获取更多选项.

(e).所有基于Vulkan的过滤器:

如果FFmpeg构建为支持 Vulkan 后端,则将提供新的过滤器,可以通过以下方式列出:

ffmpeg -filters | grep vulkan

这些过滤器最有利于VAAPI和AMD的AMF互操作性,其***享的HWContext可用于大规模加速扩展等功能.特别是AMD的用例,允许您使用Vulkan执行硬件加速的扩展,这对于AMF编码器的实时吞吐量至关重要,因为FFmpeg中AMF的当前实现缺少缩放过滤器.将来可能会更改为 Khronos完成了用于视频编码的Vulkan扩展.

基于FFmpeg的基于Vulkan的比例过滤器示例在具有NVDEC H/W加速和NVENC编码的NVIDIA GPU上运行:

 ffmpeg -threads 1 -loglevel info -nostdin -y \
   -fflags +genpts-fastseek \
   -init_hw_device cuda=cuda:0 -filter_hw_device cuda \
   -hwaccel nvdec -hwaccel_output_format cuda -extra_hw_frames 3 \
   -reinit_filter 1 -vsync 1 -async 1 -filter_threads 2 -filter_complex_threads 2 \
   -i input.mp4 -filter_complex \
  "[0:v]hwupload=derive_device=vulkan,split=2[s0][s1]; \
   [s0]scale_vulkan=w=1920:h=1080:scaler=0,hwupload=derive_device=cuda[v0]; \
   [s1]scale_vulkan=w=1280:h=720:scaler=0,hwupload=derive_device=cuda[v1]" \
  -map "[v0]" -b:v:0 5800k -minrate:v:0 5800k -maxrate:v:0 5800k -bufsize:v:0 5800k -c:v:0 h264_nvenc -r:v:0 ntsc \
  -profile:v:0 high -preset:v:0 llhp -rc:v:0 cbr_ld_hq -g:v:0 60 -gpu:v:0 0 -strict_gop:v:0 1 -bf:v:0 0 \
  -map "[v1]"  -b:v:1 4000k -minrate:v:1 4000k -maxrate:v:1 4000k -bufsize:v:1 4000k -c:v:1 h264_nvenc -r:v:1 ntsc \
  -profile:v:1 high -preset:v:1 llhp -rc:v:1 cbr_ld_hq -g:v:1 60 -gpu:v:1 0 -strict_gop:v:1 1 -bf:v:1 0 \
  -map 0:a -c:a libfdk_aac -ac 2 -ar 48000 -b:a 128k \
  -flags +global_header+cgop \
  -max_muxing_queue_size 9000000 -f tee  \
  "[select=\'v:0,a\':f=mp4]'hq.mp4'| \
   [select=\'v:1,a\':f=mp4]'med.mp4'"
 

查看上面的代码段如何利用 hwupload 的过滤器设备推导功能将Vulkan H/W上下文插入到复杂的过滤器链中.

与OpenCL和基于Vulkan的过滤器的性能有关的注意事项:请考虑由过滤器链(如hwuploadhwdownload)引入的机制可能会引入您的管道的任何间接费用,在系统内存和相关加速器之间来回上载纹理将影响性能,因此在需要/需要时(通过format过滤器)格式化转换操作也将如此. 在这种情况下,***利用 hwmap 过滤器,并在适用的情况下得出上下文.例如,如果hwmap进行OpenCL设备派生和反向映射的机制. rel ="nofollow noreferrer"> cl_intel_va_api_media_sharing OpenCL扩展存在.它通常由 Beignet ICD 提供,而在其他版本中则不存在,例如更新的 Neo OpenCL驱动程序.

3.硬件加速的解码器(及其关联的包装器)::根据您的输入源和NVIDIA GPU的功能(基于世代),您还可以利用基于CUVID或NVDEC的硬件加速.这些方法的不同之处在于它们如何在加速器上实时处理纹理,并且在使用它们时评估其他因素(例如VRAM利用率)是明智的. 通常,如果需要,您可以利用基于CUVID的hwaccel进行反交错等操作.通过以下方式查看其用法:

ffmpeg -h decoder=h264_cuvid
ffmpeg -h decoder=hevc_cuvid
ffmpeg -h decoder=mpeg2_cuvid

但是,请注意,使用以下方法处理 MBAFF 编码的内容时,建议不要使用需要双重去隔行的这些解码器,因为NVIDIA尚未在后端实现MBAFF支持.看看此线程,以了解更多信息.

最后:评估硬件加速卸载(过滤,编码和解码)在何时何地提供优势或可接受的权衡(质量,功能支持和可靠性)方面是明智的.您的管道在生产中部署之前.在决定何时以及何时卸载管道的某些部分时,这是一种与供应商无关的方法,同样适用于NVIDIA的解决方案.

有关更多信息,请参阅FFmpeg Wiki中的硬件加速条目.

警告::请确保将解码器的线程数降低到1.这些hwaccel,尤其是cuvid(和nvdec包装器)不实现线程支持.实际上,他们会向您发出警告如果线程数超过32.对于这些解码器,线程数将显式假定为表面数.

在输入之前将-threads 1传递给ffmpeg .线程的参数位置很重要.在这种情况下,它将解码器的线程数设置为1.输入后,它将FFmpeg的编码器和复用器(如果支持线程化)使用的线程数设置为配置值.