NVIDIA FFmpeg 转码技术分析

所有从 Kepler 一代开始的 NVIDIA GPUs 都支持完全加速的硬件视频编码,而从费米一代开始的所有 GPUs 都支持完全加速的硬件视频解码。截至 2019 年 7 月,Kepler、Maxwell、Pascal、Volta 和 Turing 一代 GPUs 支持硬件编码,Fermi、Kepler、Maxwell、Pascal、Volta 和 Turing 一代 GPUs 支持硬件解码。

高质量视频应用的处理需求对广播和电信网络提出了限制。消费者行为已经发生了变化,这在 OTT 视频订阅和实时流媒体迅速普及的趋势中表现得很明显。现在所有的社交媒体应用程序都在各自的平台上加入了这一功能。随着消费者从观看点播视频转向观看直播视频,直播将推动手机和 Wi-Fi 的整体视频数据流量增长。

分发给观众的视频内容通常被转换成几个自适应比特率( ABR )配置文件以进行传输。生产中的内容可能以大量编解码器格式之一到达,这些格式需要转换为另一种格式以供分发或存档。

这使得视频转码成为高效视频管道中的一个关键部分——无论是 1 : N 还是 M : N 配置文件。理想的转码解决方案需要在成本(美元/流)和能效(瓦特/流)方面具有成本效益,同时为数据中心提供具有最大吞吐量的高质量内容。视频提供商希望降低向更多屏幕提供更多高质量内容的成本。

在各个方面生成的大量视频内容需要对视频编码、解码和转码进行健壮的硬件加速。让我们看看 NVIDIA GPUs 是如何整合专用视频处理硬件的,以及如何利用它。

NVIDIA 编解码硬件

NVIDIA GPUs 上配备了片上硬件编码器和解码器单元,通常称为 NVENC 和 NVDEC。与 CUDA 核心分开, NVENC / NVDEC 运行编码或解码工作负载,不会减慢同时运行的图形或 CUDA 工作负载的执行。

NVENC 和 NVDEC 支持许多重要的编解码编解码器。 NVIDIA 。最新的支持矩阵可以在 GPU 上找到。

图 1 : GPU 硬件功能

基于 FFmpeg 的硬件加速转码

在对视频数据进行转码时,通常使用 FFmpeg 库 。硬件加速极大地提高了工作流的性能。图 2 显示了 FFmpeg 转换过程的不同元素。

图片 2 :使用 NVIDIA 硬件加速的 FFmpeg 流水线转码

FFmpeg 通过 h264_cuvid 、 hevc_cuvid 和 h264_nvenc 、 hevc_nvenc 模块支持硬件加速解码和编码。从源代码构建时激活对硬件加速的支持需要一些额外的步骤:

  • Clone FFmpeg git 存储库 https://git.ffmpeg.org/ffmpeg.git
  • 从 NVIDIA 网站 下载并安装兼容的驱动程序
  • 下载并安装 CUDA 工具箱
  • Clone nv-codec-headers 存储库 并仅使用此存储库作为头进行安装: make install
  • 使用以下命令配置 FFmpeg (使用正确的 CUDA 库路径):

./configure --enable-cuda --enable-cuvid --enable-nvenc --enable-nonfree --enable-libnpp --extra-cflags=-I/usr/local/cuda/include --extra-ldflags=-L/usr/local/cuda/lib64

  • 使用多个进程进行构建,以提高构建速度并抑制过度输出: make -j -s

使用 FFmpeg 进行软件 1 : 1 转码非常简单:

ffmpeg -i input.mp4 -c:a copy -c:v h264 -b:v 5M output.mp4

但这将是缓慢的,它只使用基于 CPU 的软件编码器和解码器。使用硬件编码器 NVENC 和解码器 NVDEC 需要添加更多参数来告诉 ffmpeg 使用哪个编码器和解码器。最大化转码速度还意味着确保解码后的图像保存在 GPU 存储器中,以便编码器能够有效地访问它。

ffmpeg -vsync 0 -hwaccel cuvid -c:v h264_cuvid -i input.mp4 -c:a copy -c:v h264_nvenc -b:v 5M output.mp4

如果没有 -hwaccel-cuvid 选项,解码后的原始帧将通过 PCIe 总线复制回系统内存,如图 3 所示。稍后,相同的图像将通过 PCIe 复制回 GPU 内存,以便在 GPU 上进行编码。这两个额外的传输由于传输时间而造成延迟,并将增加 PCIe 带宽占用。

图&& 3 :没有 hAccel 的内存流(& M )

添加 -hwaccel-cuvid 选项意味着原始解码帧将不会被复制,转码将更快、使用更少的系统资源,如图 4 所示。

hwaccel 的内存流

给定 PCIe 带宽限制,复制未压缩的图像数据会使 PCIe 总线迅速饱和。防止系统和 GPU 内存之间不必要的复制,使用 -hwaccel-cuvid 的吞吐量比不使用 -hwccel-cuvid 的未优化调用高出 2 倍。

处理筛选器

代码转换通常不仅涉及到更改输入流的格式或比特率,还包括调整其大小。有两个选项可用于调整 GPU 上的大小:使用 npp_scale 过滤器或 nvcuvid resize 选项。当从一个输入到一个具有不同分辨率( 1 : 1 转码)的输出流转码时,可以使用 nvcuvid resize 选项。请参见下一行的示例。

ffmpeg -vsync 0 –hwaccel cuvid -c:v h264_cuvid –resize 1280x720 -i input.mp4 -c:a copy -c:v h264_nvenc -b:v 5M output.mp4

如果需要多个输出分辨率( 1 : N 转码),则 scale_npp 滤波器可以调整 GPU 上解码帧的大小。通过这种方式,可以生成具有多个不同分辨率的多个输出流,但对所有流只使用一个调整大小的步骤。关于 1 : 2 转码的示例,请参见下一行。

ffmpeg -vsync 0 –hwaccel cuvid -c:v h264_cuvid -i input.mp4 \ -c:a copy –vf scale_npp=1280:720 -c:v h264_nvenc -b:v 5M output_720.mp4 \ -c:a copy -vf scale_npp=640:320 -c:v h264_nvenc -b:v 3M output_360.mp4

使用 -vf "scale_npp=1280:720" 将设置 scale_npp 作为解码图像的过滤器。

插值算法可以作为附加参数为 scale_npp 定义。默认情况下使用三次插值,但其它算法 MIG HT 会根据比例因子和图像提供更好的结果。建议在缩小尺度时使用超级采样算法以获得最佳质量。示例如下:

ffmpeg -vsync 0 –hwaccel cuvid -c:v h264_cuvid -i input.mp4 -c:a copy –vf scale_npp=1280:720:interp_algo=super -c:v h264_nvenc -b:v 5M output_720.mp4

混合 CPU 和 GPU 处理

有时 MIG 需要混合使用 CPU 和 hwupload_cuda 处理。例如,可能需要在 CPU 上解码,因为 -hwaccel cuvid 解码器不支持该格式,或者 GPU 上没有滤波器。在这种情况下,不能使用 GPU 标志。相反,需要使用 GPU 过滤器将数据从系统上传到 GPU 内存。下面的示例中,由于未设置 -hwaccel cuvid ,在 GPU 上解码 H . 264 流并将其下载到系统内存中。进入滤波器应用于系统存储器中,并使用 hwupload_cuda 滤波器将处理后的图像上传到 GPU 存储器。最后,使用 scale_npp 缩放图像并在 GPU 上编码。

ffmpeg -vsync 0 -c:v h264_cuvid -i input.264 -vf "fade,hwupload_cuda,scale_npp=1280:720" -c:v h264_nvenc output.264

Multi-GPU

当在一个系统中使用多个 GPUs 时,编码和解码工作必须显式地分配给 GPU。 GPUs 由其索引号标识;默认情况下,所有工作都在索引为 0 的 GPU 上执行。使用以下命令获取系统中所有 NVIDIA GPUs 及其相应的 ID 号的列表:

ffmpeg -vsync 0 -i input.mp4 -c:v h264_nvenc -gpu list -f null –

一旦理解了索引,就可以使用 -hwaccel_device 索引标志来设置解码和编码的活动 GPU 。在下面的例子中,工作将在索引为 1 的 GPU 上执行。

ffmpeg -vsync 0 -hwaccel cuvid -hwaccel_device 1 -c:v h264_cuvid -i input.mp4 -c:a copy -c:v h264_nvenc -b:v 5M output.mp4

优化

为了获得最佳的吞吐量,所有的编码器和解码器单元都应该被尽可能地利用。 nvidia-smi 可用于生成有关 NVENC 、 NVDEC 和一般 GPU 利用率的实时信息。

nvidia-smi dmon nvidia-smi -q -d UTILIZATION

根据这些结果可以采取多种措施。如果编码器利用率低, MIG 可以引入另一个转码管道,该管道使用 CPU 解码和 NVENC 编码来为硬件编码器生成额外的工作负载。

使用 CPU 筛选器时, PCIe 带宽 MIG ht 成为瓶颈。如果可能,筛选器应在 GPU 上运行。 FFmpeg 中有几个 CUDA 过滤器,可以用作模板来实现高性能 CUDA 过滤器。

通过使用 GPU SDK 的 NVIDIA 可视化分析器分析 ffmpeg 应用程序,可以始终跟踪主机和设备之间的 GPU 利用率和内存传输。只需启动“ Run application to generateCPU and GPU timeline ”,然后选择带有相关 CLI 选项的 ffmpeg 应用程序。图 5 说明了应用程序

图 5 :绿色块显示 CUDA 内核完成的颜色空间转换,而黄色块显示主机和设备之间的内存传输。使用 visual profiler ,用户可以轻松地跟踪在 GPU 上执行的操作,例如 CUDA 加速的过滤器和数据传输,以确保不会执行过多的内存拷贝。

通过使用 --disable-stripping CLI 选项编译 ffmpeg 来收集 CPU – 端性能统计信息,以启用性能分析。

这可以防止编译器剥离函数名,以便像 Gprof 或 visual studio profiler 这样的商品探查器可以收集性能统计信息。 CPU 在硬件加速开启的情况下,负载水平应较低,并且大部分时间应花费在视频代码 SDK API 调用中,这些调用标记为“外部代码”,因为函数名从驱动程序库中被删除。图 6 显示了一个示例屏幕截图。

图 6 : visualstudio 的 ffmpeg 性能评测

推荐

有关如何使用 FFmpeg 的更多示例以及可用的高级质量设置,请查看“ 使用 FFmpeg 和 NVIDIA GPU 硬件加速 “向导。

结论

FFmpeg 是一个强大而灵活的开源视频处理库,具有硬件加速的解码和编码后端。允许快速的视频处理和完整的 NVIDIA GPU 硬件支持,只需几分钟。 Gprof 、 visualprofiler 和 microsoftvisualstudio 等商品开发工具可以用于精细的性能分析和调优。

NVIDIA FFmpeg 转码技术分析的更多相关文章

  1. FFmpeg源码简单分析:libswscale的sws_scale()

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

  2. FFmpeg源码简单分析:结构体成员管理系统-AVOption

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

  3. java运用FFMPEG视频转码技术

    基于windows系统安装FFMPEG转码技术 http://wenku.baidu.com/link?url=z4Tv3CUXxxzLpa5QPI-FmfFtrIQeiCYNq6Uhe6QCHkU- ...

  4. FFmpeg源码结构图 - 解码

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

  5. FFmpeg资料来源简单分析:libswscale的sws_getContext()

    ===================================================== FFmpeg库函数的源代码的分析文章: [骨架] FFmpeg源码结构图 - 解码 FFmp ...

  6. FFmpeg源码结构图 - 编码

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

  7. FFmpeg的HEVC解码器源码简单分析:解析器(Parser)部分

    ===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...

  8. 最新版ffmpeg源码分析

    最新版ffmpeg源码分析一:框架 (ffmpeg v0.9) 框架 最新版的ffmpeg中发现了一个新的东西:avconv,而且ffmpeg.c与avconv.c一个模样,一研究才发现是libav下 ...

  9. FFmpeg的HEVC解码器源码简单分析:概述

    ===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...

随机推荐

  1. VRRP中的上层回的路由

    如图,PC1和PC2处于不同网段,他们到AR3都有两条路可以选,现在要让他们到达AR3负载均衡,并且当AR1和 AR2的其中一个路由器挂了之后,他们仍然可以正常到达AR3. 他们去往AR3的VRRP的 ...

  2. Python中Scapy网络嗅探模块的使用

    目录 Scapy scapy的安装和使用 发包 发包和收包 抓包 将抓取到的数据包保存 查看抓取到的数据包 格式化输出 过滤抓包 Scapy scapy是python中一个可用于网络嗅探的非常强大的第 ...

  3. Sqlmap的使用详解

    目录 Sqlmap Sqlmap的简单用法 探测指定URL是否存在SQL注入漏洞 查看数据库的所有用户 查看数据库所有用户名的密码 查看数据库当前用户 判断当前用户是否有管理权限 列出数据库管理员角色 ...

  4. IDEA 这样设置,好看到爆炸!!!

    Hello,大家好,我是楼下小黑哥. 今天这篇文章是次条视频的文案,这里推荐大家直接看视频学习. IDEA 这样设置,好看到爆炸!!!#01 今天这期我们来分享几个美化 IDEA 设置技巧,让你的 I ...

  5. 初始化mysql报错bin/mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory

    原因:缺少libaio.so.1 解决办法:安装即可 yum install -y libaio

  6. vuex、localStorage、sessionStorage之间的区别

    vuex存储在内存中,localStorage以文件形式存储在本地,sessionStorage针对一个session(阶段)进行数据存储. 当页面刷新时vuex存储的数据会被清除,localStor ...

  7. 2021ArchSummit全球架构师峰会上,大家在聊些什么

    大会PPT公开下载链接:https://ppt.infoq.cn/list/assh2021 大会主要情况介绍 2021 ArchSummit全球架构师峰会是该大会正式成立的第十年,是极客邦科技旗下I ...

  8. 从effective C++中窥探C++11特性

    这几天在看effective C++3rd,这本书算是比较经典的一本入门C++的书了.虽然年代比较久远书中讲的好多模式已经被的新特性取代了,但是从这些旧的模式中可以了解到一些C++新特性设计的初衷,也 ...

  9. Linux(深度)系统安装富士施乐(网络)打印机

    一般来讲,linux系统识别打印机没有问题,重点难点在于后面设置.此文特别感谢:河北石龙的陈一繁销售代表.P288dw施乐官网并未提供Linux的驱动并在安装过程中遇到很多问题,其不厌其烦的为我联系厂 ...

  10. Sed常用功能个人整理

    Sed常用功能个人整理 AsdilFibrizo关注 2019.06.24 10:23:41字数 240阅读 15 Sed对1G以下的数据效率很高这里介绍一些个人在工作中遇到的sed问题 1.查找字段 ...