FFmpeg 硬件加速(硬解码)介绍

概述

本文主要针对ffmpeg支持的硬解码做一个总结阐述。

许多平台提供对专用硬件的访问,以执行一系列与视频相关的任务。使用此类硬件可以更快地完成某些操作,例如解码、编码或过滤,或者使用更少的其他资源(尤其是 CPU),但可能会产生不同或较差的结果,或者施加仅使用软件时不存在的额外限制。在类似 PC 的平台上,视频硬件通常集成到 GPU(来自 AMD、Intel 或 NVIDIA)中,而在移动 SoC 类型的平台上,它通常是一个独立的 IP 核(许多不同的供应商)。

硬件解码器将产生与软件解码器相同的输出,但可能使用更少的功率和 CPU 来这样做。功能支持各不相同——对于具有许多不同配置文件的更复杂的编解码器,硬件解码器很少实现所有这些(例如,硬件解码器往往不会在 H.264 的 8 位深度下实现 YUV 4:2:0 以外的任何内容)。许多硬件解码器的一个共同特点是能够在适合其他组件使用的硬件表面中生成输出(对于独立显卡,这意味着表面在卡上的内存中而不是在系统内存中)——这通常对播放很有用,因为在呈现输出之前不需要进一步复制,并且在某些情况下,它还可以与支持硬件表面输入的编码器一起使用,以避免在转码情况下进行任何复制。

硬件编码器生成的输出质量通常比好的软件编码器(如 x264)低得多,但通常速度更快并且不使用太多 CPU 资源。(也就是说,它们需要更高的比特率才能以相同的感知质量进行输出,或者在相同的比特率下以较低的感知质量进行输出。)

具有解码和/或编码能力的系统还可以提供对其他相关过滤功能的访问。像缩放和去隔行这样的事情很常见,其他后处理可能取决于系统。在硬件表面可用的情况下,这些过滤器通常会作用于它们而不是系统内存中的正常帧。

有许多不同标准化状态的不同 API 可用。FFmpeg 提供对其中许多的访问,并提供不同的支持。

平台 API 可用性

注:
Y 完全可用。
P 部分支持(某些设备/某些功能)。
N 不可能。

FFmpeg API 实现状态

- 不适用于此 API。

Y 已经支持。

N 可能但未实施。

F 尚未整合,但正在这方面开展工作。

与ffmpeg命令行工具一起使用

通过 -hwaccel选 项启用内部 硬件解码器。软件解码器默认启动,但如果它检测到可在硬件中解码的流,则它将尝试将所有重要处理委托给该硬件。如果流无法在硬件中解码(例如,它是不受支持的编解码器或配置文件),那么它仍将在自动软解码。如果硬件需要特定设备才能运行(或需要区分多个设备,例如是否有多个显卡可用),则可以使用-hwaccel_device来选择一个.

通过使用-codec:v选项设置特定的解码器来使用外部封装器解码器。通常,它们被命名codec_api(例如:h264_cuvid)。这些解码器需要事先知道编解码类型,并且如果流是不支持类型,不支持任何回退到软解码。

通过-codec:v选择编码器封装. 编码器通常有很多选择——查看特定编码器的文档以了解详细信息。

硬件过滤器可以像任何其他过滤器一样用于过滤器中。但是请注意,他们可能不支某些软解过滤器常见格式——在这种情况下,可能有必要利用hwupload和hwdownload过滤器实例来再硬件表面和正常的存储之间移动帧数据。

名词解释

VDPAU

全称:Video Decode and Presentation API for Unix,针对Unix的视频解码和演示API。由 NVIDIA 为 Unix/Linux 系统开发。要启用此功能,您通常需要发行版中的libvdpau开发包和兼容的显卡。

请注意,VDPAU 不能用于对内存中的帧进行解码,压缩后的帧由 libavcodec 发送到 VDPAU 支持的 GPU 设备,然后可以使用 VDPAU API 访问解码后的图像。这不是由 FFmpeg 自动完成的,而是必须在应用程序级别完成(例如检查ffmpeg_vdpau.c使用的文件ffmpeg.c)。另外,请注意,使用此 API 无法将解码的帧拷贝回 RAM,例如,如果您需要再次对解码的帧进行编码(例如,在服务器上进行转码时)。

目前通过 libavcodec 中的 VDPAU 支持几种解码器,特别是 H.264、MPEG-1/2/4 和 VC-1。

VAAPI

全称:Video Acceleration API,视频加速 API (VAAPI) 是一种非专有且免版税的开源软件库 (“libva”) 和 API 规范,最初由英特尔开发,但可与其他设备结合使用。

它可用于访问 Intel GPU 中的 Quick Sync 硬件和 AMD GPU 中的 UVD/VCE 硬件。请参阅VAAPI。

DXVA2

全称:​Direct-X Video Acceleration API,由微软开发的(支持Windows和Xbox360)。

目前支持多种解码器,特别是 H.264、MPEG-2、VC-1 和 WMV 3。

DXVA2 硬件加速仅适用于 Windows。为了构建支持 DXVA2 的 FFmpeg,您需要安装 dxva2api.h 头文件。对于MinGW的,这可以通过进行下载由VLC保持报头,并在安装它包括路径(例如在/usr/include/)。

对于 MinGW64,dxva2api.h默认提供。安装 mingw-w64 的一种方法是通过pacman存储库,可以使用以下两个命令之一进行安装,具体取决于架构:

pacman -S mingw-w64-i686-gcc 
pacman -S mingw-w64-x86_64-gcc

要启用 DXVA2,请使用–enable-dxva2ffmpeg 配置开关。

要测试解码,请使用以下命令:

ffmpeg -hwaccel dxva2 -threads 1 -i INPUT -f null - -benchmark

VideoToolbox

VideoToolbox,只支持在MacOS的H.264 解码,包含在 FFmpeg/libavcodec 中。

要在 macOS 中使用硬件编码,只需分别使用编码器-c:v h264_videotoolbox或-c:v hevc_videotoolbox对H.264 或 HEVC进行编码。通过ffmpeg -h encoder=…来查看编码器选项。值得注意的是,VideoToolbox 不支持恒定质量 (CRF) 编码。比特率-b:v …是平衡大小与质量的主要杠杆。

CUDA(NVENC/NVDEC)

NVENC 和 NVDEC 是 NVIDIA 的硬件加速编码和解码 API。它们曾经被称为 CUVID。它们可用于在 Windows 和 Linux 上进行编码和解码。FFmpeg 将 NVENC/NVDEC 称为 CUDA。

NVENC

NVENC 可用于 H.264 和 HEVC 编码。FFmpeg 通过h264_nvenc和hevc_nvenc编码器支持 NVENC 。为了在 FFmpeg 中启用它,您需要:

一块支持硬编码的N卡GPU,点此查看您的显卡是否支持

操作系统支持的显卡驱动程序

+ NVIDIA的编解码器SDK(点此下载)或通过-enable-cuda-llvm选项编译的FFmpeg

ffmpeg配置为–enable-nvenc(如果在配置时检测到驱动程序,则默认)

注意: FFmpeg 使用自己稍微修改过的运行时加载器来处理 NVIDIA 的 CUDA/NVENC/NVDEC 相关库。如果你从configure编译中得到一个关于缺少ffnvcodec的错误,这个项目是你所需要的。它有一个带有安装目标make install PREFIX=/usr的Makefile:. FFmpeg 将在pkg-config 文件中查找ffnvcodec.pc,来确保它在您的PKG_CONFIG_PATH中。

这意味着在编译 ffmpeg 之前运行以下内容就足够了:

git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git 
cd nv-codec-headers 
make 
sudo make install

编译完成后就可以使用NVENC了。

用法示例:

ffmpeg -i input -c:v h264_nvenc -profile high444p -pixel_format yuv444p -preset default output.mp4

您可以使用ffmpeg -h encoder=h264_nvenc或来查看可用的预设、其他选项和编码器信息ffmpeg -h encoder=hevc_nvenc。

注意:如果No NVENC capable devices found出现错误,请确保编码为支持的像素格式。请参阅如上所示的编码器信息。

NVDEC/CUVID

NVDEC 为 H.264、HEVC、MJPEG、MPEG-1/2/4、VP8/VP9、VC-1 提供解码器。编解码器支持硬件(见GPU兼容性表)。

请注意,FFmpeg 提供 NVDEC 和 CUVID hwaccels。它们的不同之处在于帧在内存中的解码和转发方式。

全套编解码器仅在 Pascal 硬件上可用,它增加了 VP9 和 10 位支持。关于 NVENC 缺少 ffnvcodec 的说明也适用于 NVDEC。

使用 CUDA 的解码示例:

ffmpeg -hwaccel cuda -i input output

使用 CUVID 的解码示例:

ffmpeg -c:v h264_cuvid -i input output

使用 NVDEC 和 NVENC 进行全硬件转码:

ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input -c:v h264_nvenc -preset slow output

如果 ffmpeg 是在支持 libnpp 的情况下编译的,则它可用于将基于 GPU 的缩放器插入链中:

ffmpeg -hwaccel_device 0 -hwaccel cuda -i input -vf scale_npp=-1:720 -c:v h264_nvenc -preset slow output.mkv

该-hwaccel_device选项可用于指定 ffmpeg 中硬解码要使用的 GPU。

libmfx

libmfx 是 Intel 的专有库,用于在 Linux 和 Windows 上使用 Quick Sync 硬件。在 Windows 上,它是比使用 DXVA2/D3D11VA 访问之外的更高级功能的主要方式,尤其是编码。在 Linux 上,它有一些不同的功能集,有助于某些需要最大吞吐量的用例。

请参阅快速同步。

OpenCL

OpenCL的可用于多个滤波器。要构建,需要 OpenCL 1.2 或更高版本的头文件,以及要链接到的 ICD 或 ICD 加载器 - 建议(但不是必需)与 ICD 加载器链接,以便可以在运行时选择实现而不是构建时间。在运行时,需要 OpenCL 1.2 驱动程序 - 大多数 GPU 制造商将提供一个作为其标准驱动程序的一部分。CPU 实现也可用,但可能比直接在 ffmpeg 中使用本机过滤器慢。

OpenCL 可以与其他 GPU API 互操作,以避免 GPU 和 CPU 内存之间的冗余副本。支持的方法有:

DXVA2:仅 NV12 表面,所有平台。

D3D11:仅适用于 Intel 的 NV12 纹理。

VAAPI:所有表面类型。

ARM Mali:所有表面类型,通过 DRM 对象共享。

libmfx:仅 NV12 表面,通过 VAAPI 或 DXVA2。

AMD UVD/VCE

AMD UVD 可用于在 Linux 上的 Mesa 中通过 VDPAU 和 VAAPI 进行解码。VCE 也有一些对通过 VAAPI 编码的初步支持,但应该被视为实验性的。

在 Windows 上,UVD 可通过标准 DXVA2/D3D11VA API 访问,而 VCE 则通过 AMF 支持。

版权声明:本文为CSDN博主「SunkingYang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:FFmpeg 硬件加速(硬解码)介绍

★文末名片可以免费领取音视频开发学习资料,内容包括(FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)以及音视频学习路线图等等。

见下方!↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

猜你喜欢

转载自blog.csdn.net/yinshipin007/article/details/131869946