FFmpeg硬解码

今日头条

1098人已加入

描述

版权声明:本文为博主翻译文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Tosonw/article/details/90178195


原文链接:https://trac.ffmpeg.org/wiki/HWAccelIntro                

一、FFmpeg:HWAccelIntro

原文(英文):https://trac.ffmpeg.org/wiki/HWAccelIntro
许多平台提供对专用硬件的访问,以执行一系列与视频相关的任务。使用这样的硬件允许诸如解码,编码或过滤之类的一些操作更快地完成或使用更少的其他资源(特别是CPU),但是可能给出不同或较差的结果,或者施加仅在使用软件时不存在的附加限制。在类似PC的平台上,视频硬件通常集成到GPU(来自AMD,Intel或NVIDIA),而在移动SoC类型平台上,它通常是独立的IP核(许多不同的供应商)。

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

硬件编码器通常生成的输出质量明显低于x264等软件编码器,但通常速度更快,CPU资源也不多。(也就是说,它们需要更高的比特率来使输出具有相同的感知质量,或者它们以相同的比特率以较低的感知质量进行输出。)

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

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

1.平台API可用性

音频硬解码

2.FFmpeg API实现状态

音频硬解码

与ffmpeg命令行工具一起使用

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

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

编码器包装器由-codec:v选择。编码器通常有很多选项 - 有关详细信息,请查看特定编码器的文档。

硬件过滤器可以像任何其他过滤器一样用在过滤器图形中。但请注意,它们可能不支持与软件过滤器相同的任何格式 - 在这种情况下,可能需要使用hwupload和hwdownload过滤器实例在硬件表面和普通内存之间移动帧数据。

3.VDPAU

https://http.download.nvidia.com/XFree86/vdpau/doxygen/html/index.html
视频解码和演示API为Unix。由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。

4.VAAPI

https://trac.ffmpeg.org/wiki/Hardware/VAAPI
视频加速API(VAAPI)是一种非专有且免版税的开源软件库(“libva”)和API规范,最初由Intel开发,但可与其他设备结合使用。

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

5.DXVA2

https://msdn.microsoft.com/en-us/library/windows/desktop/cc307941(v=vs.85).aspx
直接-X视频加速API,由微软开发的(支持Windows和Xbox360)。

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

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

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

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

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

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

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

6.VideoToolbox

https://developer.apple.com/documentation/videotoolbox
VideoToolbox,只支持在MacOS。H.264解码在FFmpeg / libavcodec中可用。

7.NVENC / NVDEC

NVENC和NVDEC是NVIDIA的硬件加速编码和解码API。他们曾经被称为CUVID。它们可用于Windows和Linux上的编码和解码。

NVENC

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

一个支持GPU
支持您的操作系统的驱动程序
在NVIDIA编解码器SDK

ffmpeg使用–enable-nvenc配置(如果在配置时检测到驱动程序,则为默认值)
注意: FFmpeg对NVIDIA的CUDA / NVENC / NVDEC相关库使用自己稍微修改过的运行时加载程序。如果你从一个错误配置抱怨缺少ffnvcodec,这个项目是你所需要的。它有一个带有安装目标的工作Makefile:make install PREFIX = / usr。FFmpeg将查找名为ffnvcodec.pc的 pkg-config文件。确保它在PKG_CONFIG_PATH中。

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

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

编译后,您可以使用NVENC。

用法示例:

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

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

注意:如果您发现无NVENC功能设备错误,请确保您使用支持的像素格式进行编码。请参阅上面显示的编码器信息。

NVDEC / CUVID

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

请注意,FFmpeg提供NVDEC和CUVID hwaccel。它们在帧中如何解码和转发在内存中有所不同。

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

使用NVDEC进行样本解码:

ffmpeg -hwaccel nvdec input output1

使用CUVID进行样本解码:

./ffmpeg-git -hwaccel cuvid -c:v h264_cuvid -i input output1

CUVID和NVENC的全硬件转码:

ffmpeg -hwaccel cuvid -c:v h264_cuvid -i input -c:v h264_nvenc -preset slow output1

如果编译了ffmpeg并支持libnpp,则可以使用它将基于GPU的缩放器插入到链中:

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

该-hwaccel_device选项可用于指定要通过的ffmpeg的hwaccel的使用的GPU。

8.libmfx

libmfx是英特尔的专有库,用于在Linux和Windows上使用Quick Sync硬件。在Windows上,除了可通过DXVA2 / D3D11VA访问的功能外,它是使用更高级功能的主要方式,特别是编码。在Linux上,它具有非常有限的功能集并且难以使用,但对于某些需要最大吞吐量的用例可能会有所帮助。

9.OpenCL

原文(英文):https://www.khronos.org/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:仅通过VAAPI或DXVA2的NV12表面。

10.AMD UVD / VCE

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

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

11.外部资源

multimedia.cx:如何玩硬件加速视频在Mac:https://multimedia.cx/eggs/mac-hwaccel-video/
libav用户:硬件加速解码:https://lists.ffmpeg.org/pipermail/libav-user/2013-September/005463.html
堆栈溢出:如何使用硬件加速与ffmpeg的:https://stackoverflow.com/questions/23289157/how-to-use-hardware-acceleration-with-ffmpeg

二、硬件:VAAPI

原文(英文):https://trac.ffmpeg.org/wiki/Hardware/VAAPI

1.平台支持

Intel / i965

请参阅QuickSync:https://trac.ffmpeg.org/wiki/Hardware/QuickSync

AMD / Mesa

Mesa VAAPI驱动程序使用所有最新AMD显卡和APU中的UVD(统一视频解码器)和VCE(视频编码引擎)硬件。

所有GCN GPU(自Southern Islands以来)都支持H.264,MPEG-2,MPEG-4第2部分和VC-1解码。GCN 3(火山岛)和H.265 10位与GCN 4(北极群岛)一起增加了H.265支持。可能支持也可能不支持较旧的GPU。

默认情况下,由于VAAPI限制,MPEG-4第2部分被禁用(主要的英特尔驱动程序从未实现它,所以它没有得到太多测试)。将环境变量VAAPI_MPEG4_ENABLED设置为1,无论如何都要尝试使用它。

H.264编码正在使用GCN GPU,但仍然不完整。Mesa还没有其他编解码器支持编码。

由于GPU内存中的数据布局,Mesa中的编码和隔行扫描支持是不兼容的。默认情况下,帧被分隔为字段,并且支持隔行扫描视频,但不支持编码。将环境变量VAAPI_DISABLE_INTERLACE设置为1以便能够使用编码器(但没有任何隔行视频支持)。

2.设备选择

需要将libva驱动程序连接到DRM设备才能工作。这可以直接连接,也可以通过正在运行的X服务器连接。在使用Standlone时,通常最好使用DRM渲染节点(/ dev / dri / render *) - 如果您确实想要处理X内的表面(例如,使用DRI2),则仅使用X连接。

在ffmpeg中,可以使用-init_hw_device选项创建命名的全局设备:

ffmpeg -init_hw_device vaapi=foo:/dev/dri/renderD1281

通过解码hwaccel,可以使用-hwaccel_device选项为每个输入流提供先前初始化的设备:

ffmpeg -init_hw_device vaapi=foo:/dev/dri/renderD128 -hwaccel vaapi -hwaccel_device foo -i ...1

如果只使用一个流,-hwaccel_device也可以直接接受设备路径:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -i ...1

如果过滤器需要设备(例如,hwupload过滤器),则可以使用-filter_hw_device选项指定过滤器图中使用的设备:

ffmpeg -init_hw_device vaapi=foo:/dev/dri/renderD128 -i ... -filter_hw_device foo -filter_complex ...hwupload... ...1

如果您在同一台计算机上有多个可用设备(例如,Intel集成GPU和AMD独立显卡),则可以同时使用它们来解码不同的流:

ffmpeg -init_hw_device vaapi=intel:/dev/dri/renderD128 -init_hw_device vaapi=amd:/dev/dri/renderD129 -hwaccel vaapi -hwaccel_device intel -i ... -hwaccel vaapi -hwaccel_device amd -i ...1

(参见< http://www.ffmpeg.org/ffmpeg.html#toc-Advanced-Video-options >有关这些选项的更多细节)。

最后,在带有过滤器的单设备情况下,-vaapi_device选项可能更方便。

ffmpeg -vaapi_device /dev/dri/renderD1281

行为等同于:

ffmpeg -init_hw_device vaapi=vaapi0:/dev/dri/renderD128 -filter_hw_device vaapi01

3.Surface Formats

VAAPI使用的硬件编解码器无法访问任意内存中的帧数据。因此,在使用之前,需要将所有帧数据上载到连接到适当设备的硬件表面。ffmpeg中的所有VAAPI硬件表面都由vaapi pixfmt 表示(但内部布局在此处不可见)。

hwaccel解码器通常以相关的硬件格式输出帧,但默认情况下,ffmpeg实用程序将输出帧下载到普通内存,然后再将它们传递给下一个组件。这使得解码器可以在没有任何其他选项的情况下更快地进行解码:

ffmpeg -hwaccel vaapi ... -i input.mp4 -c:v libx264 ... output.mp41

对于其他输出,选项-hwaccel_output_format可用于指定要使用的格式。这可以是软件格式(格式可用,取决于驱动程序),也可以是vaapi硬件格式,表示不应下载表面。

例如,要仅解码并对结果不执行任何操作:

ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi ... -i input.mp4 -f null -1

这可以仅用于测试解码器的速度/ CPU使用(下载操作通常会增加大量额外开销)。

当解码器输出位于硬件表面时,帧将以该形式提供给后续滤波器或编码器。该scale_vaapi和deinterlace_vaapi过滤器作用于VAAPI格式的画面缩放和respecitvely隔行他们。也有一些通用的过滤器- hwdownload,hwupload和hwmap -支持所有硬件格式,包括VAAPI(参见< http://www.ffmpeg.org/ffmpeg-filters.html#hwdownload >)。

例如,采用隔行输入,解码,去隔行,缩放到720p,下载到普通内存并使用libx264进行编码:

ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi ... -i interlaced_input.mp4 -vf 'deinterlace_vaapi,scale_vaapi=w=1280:h=720,hwdownload,format=nv12' -c:v libx264 ... progressive_output.mp41

4.编码

编码器仅接受输入作为VAAPI表面。如果输入在普通存储器中,则需要在将帧提供给编码器之前上载 - 在ffmpeg实用程序中,可以使用hwupload过滤器。它将上传到与软件框架布局相同的表面,因此可能需要在之前添加格式过滤器以使输入格式正确(硬件通常需要nv12布局,但大多数软件功能使用yuv420p)布局)。所述hwupload滤波器还需要一个设备上传到,需要创建过滤器图形之前被定义。

因此,要为某些输入使用默认解码器,然后将帧上传到VAAPI并使用H.264和默认设置进行编码:

ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 -vf 'format=nv12,hwupload' -c:v h264_vaapi output.mp41

如果已知输入是硬件可解码的,那么我们可以使用hwaccel:

ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device /dev/dri/renderD128 -i input.mp4 -c:v h264_vaapi output.mp41

最后,当输入可能是或不是硬件可解码时,我们可以这样做:

ffmpeg -init_hw_device vaapi=foo:/dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device foo -i input.mp4 -filter_hw_device foo -vf 'format=nv12|vaapi,hwupload' -c:v h264_vaapi output.mp41

这是因为解码器将输出vaapi表面(如果hwaccel可用)或软件帧(如果不可用)。在第一种情况下,它匹配vaapi格式,而hwupload什么都不做(它通过硬件帧不变)。在第二种情况下,它匹配nv12格式并将输入转换为该格式,然后上载。但是,根据选择的路径,性能可能会有很大的变化。

支持的编码器是:

编码API
H.262 / MPEG-2第2部分mpeg2_vaapi
H.264 / MPEG-4第10部分(AVC)h264_vaapi
H.265 / MPEG-H第2部分(HEVC)hevc_vaapi
MJPEG / JPEGmjpeg_vaapi
VP8vp8_vaapi
VP9vp9_vaapi

对于编解码器选项的说明,请参见< http://www.ffmpeg.org/ffmpeg-codecs.html#VAAPI-encoders >。

5.从libx264映射选项

目前不支持类似CRF的模式。唯一的恒定质量模式是CQP(恒定量化参数),其对场景内容没有适应性。但是,它允许不同帧类型的不同质量设置,通过在未引用的B帧上花费更少的比特来改善压缩 - 参见(i | b)_q(因子|偏移)选项。CQP模式不能与最大比特率或缓冲区大小组合。

支持CBR和VBR模式,但它们的输出因驱动器和设备而异(默认为VBR,设置-maxrate等于-b:v用于CBR)。HRD缓冲选项(rc_max_rate,rc_buffer_size)是有效的,并且编码器将在适当时生成buffering_period和pic_timing SEI。

没有完全类似的-preset选项。该-compression_level选项控制在编码器本地速度/质量权衡(即,努力花费在试图从当地选择喜欢的运动估计和模式选择最佳效果的量),用一个模糊的每个设备的规模。参数是一个小整数,从1到某个极限取决于设备(不超过7) - 更高的值更快/更低的流质量。另外,某些硬件(Intel gen9)支持具有更多限制功能的低功耗模式。可以通过-low_power选项访问它。

根本不支持双通道编码和前瞻 - 只能进行本地速率控制。VBR模式应该在接近总体比特率目标方面做得相当不错,但如果复杂性变化,质量将在流中发生显着变化。

三、硬件/QuickSync

原文(英文):https://trac.ffmpeg.org/wiki/Hardware/QuickSync
警告:请勿在不确定需要的情况下安装Intel Media SDK,尤其是在Linux上。在许多情况下,你不需要它,尝试使用它可能会破坏其他东西。

“Intel Quick Sync Video”是许多英特尔GPU内部可用的一组硬件功能的营销名称。

1.硬件支持

音频硬解码

2.API支持

可以通过许多不同的API访问硬件:

  • DXVA2 / D3D11VA
    这些是标准的Windows API,由英特尔图形驱动程序实现,以支持视频解码。

  • libmfx on Linux
    这是英特尔的一个库,可以作为Intel Media SDK的一部分安装,并支持编码和解码案例的子集。

  • libmfx on Windows
    这是一个随英特尔图形驱动程序提供的库,支持所有编码和解码案例。

  • Media Foundation
    另一个Windows API,通过英特尔图形驱动程序支持一些编码和解码案例。ffmpeg不支持。

  • VAAPI with i965 driver
    这是libva / VAAPI 结构的主要免费驱动程序。大多数Linux发行版打包它。

  • VAAPI with iHD driver
    Linux上libmfx的后端使用修改后的libva和VAAPI驱动程序; 这也可以由用户直接使用。

3.Linux

您可以从二进制安装媒体服务器工作室https://software.intel.com/en-us/intel-media-server-studio/。 但是,Media Server Studio仅支持有限的HW平台和Linux发行版。 整个开源媒体堆栈提供了更广泛的硬件平台和支持的Linux发行版。

Intel open source media stack
项目名: 支持的Gen GraphicsOpen Source Repo
MSDK: gen9 +https://github.com/Intel-Media-SDK/MediaSDK
Libva: GEN5 +https://github.com/intel/libva
i965驱动程序: gen5~gen9.5https://github.com/intel/intel-vaapi-driver
iHD驱动程序: gen9 +https://github.com/intel/media-driver
VAAPI VS libmfx

如果可能,强烈建议将VAAPI与i965驱动程序一起使用。如果您的用例特别需要其特定功能集,则仅使用libmfx。

  • VAAPI / i965
    在大多数Linux发行版中标准打包。
    运行所有可用的硬件,包括旧的和更便宜的设备。
    更广泛的编解码器支持。
    适用于可能也使用AMD / Nvidia硬件和Mesa的应用程序的通用API。
    可与标准API(EGL / OpenGL,OpenCL)互操作。

  • libmfx / iHD
    在某些情况下可能会提供更好的编码质量(?)。
    在某些情况下可能会提供更高的编码吞吐量(特别是在Iris图形上)。
    适用于也可在Windows上运行的应用程序的通用API。
    可与英特尔OpenCL实施互操作。

4.Windows

Windows版本MSDK可以从得到 https://software.intel.com/media-sdk

5.运行

VAAPI

请参阅硬件/ VAAPI:https://trac.ffmpeg.org/wiki/Hardware/VAAPI

libmfx

该库具有大量可供选择的选项,可能的有效值取决于版本和硬件。libavcodec尝试将常见选项明智地映射到libmfx选项,但映射是粗略的并且有漏洞,尤其是围绕速率控制。

使用无效组合可能会激发消息:“QSV运行时不支持选定的速率控制模式。请选择其他模式。” 通常这条消息是准确的,但它也可以指其他问题,如缺乏可用的设备。

6.在Linux上安装Media SDK

请注意,内核修补程序和修改过的系统库都是必需的。建议不要将它安装在任何也用于其他目的的机器上,因为它不使用正常的分配机制,并且可能意外地被其他软件包破坏/破坏。

  • 建造机器:
    建立和安装打包调度:< https://github.com/lu-zero/mfx_dispatch >。(也可以按照安装手册中的说明从Media SDK安装中提取必要的文件 - 不建议这样做,只需使用包。)
    使用–enable-libmfx构建ffmpeg。

  • 目标机器:
    确保目标计算机具有受支持的CPU。当前版本仅在昂贵的CPU(“Xeon”/“Core i”品牌)上支持gen8 / gen9图形。更便宜的CPU(“Pentium”/“Celeron”/“Atom”品牌)上的相同图形核心被明确禁用,可能是出于商业原因。
    得到一个干净的版本支持的内核版本(目前4.4:< https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.4.tar.xz >),并应用所提供的补丁。构建和安装。
    构建并安装提供的libva和libdrm树。
    运行Media SDK安装脚本以安装专有组件。
    重启。



————————————————
版权声明:本文为CSDN博主「Tosonw」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Tosonw/article/details/90178195

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分