英特尔QSV技术在FFmpeg中的实现与使用

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/vn9PLgZvnPs1522s82g/article/details/82892209 ...
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/vn9PLgZvnPs1522s82g/article/details/82892209

640?wx_fmt=jpeg


本文来自英特尔资深软件工程师张华在LiveVideoStackCon 2018讲师热身分享,并由LiveVideoStack整理而成。在分享中张华介绍了英特尔GPU硬件架构,并详细解析了英特尔QSV技术在FFmpeg中的具体实现与使用。


文 / 张华

整理 / LiveVideoStack

直播回放:

https://www.baijiayun.com/web/playback/index?classid=18091958472800&session_id=201809200&token=PLFiH_sX1NNt681rrJ0J_ZTHDO9zanYEZBBB3Q06X5q9UJKvNPUPBpuOZ7Qxt3OtBkXP5cY2MAsKp0fXMnVKLQ


大家好,今天我与大家分享的是英特尔GPU架构以及Quick Sync Video技术在FFmepge中的实现与使用。


1、处理器整体架构


640?wx_fmt=png


大家知道,英特尔的图形处理GPU被称为“核芯显卡”,与CPU集成封装在同一个芯片上,上图展示的是芯片的内部结构。


1.1 发展


640?wx_fmt=png


英特尔从lvy Bridge架构开始就尝试将GPU与CPU集成在中央处理芯片中并逐代发展到Skylake架构。初期的Ivy Bridge架构中GPU所占的面积非常小,而到现在的第五代处理器架构Skylake已经实现十分成熟的GPU集成技术,GPU在芯片中所占的面积已经超过了一半。在未来我们将推出基于PCI-E的独立显卡,为PC带来更大的图像性能提升。


1.2 基础功能模块


640?wx_fmt=png


上图展示的是一款GPU所具备的一些基础功能模块。英特尔的核芯显卡分为普通的Intel HD Graphics与性能强大的Intel Iris (Pro)Graphics,其中硬件结构的变化决定性能的高低。我们知道,GPU中的Slice个数越多,处理单元的组织方式越多,性能便越强大。Intel HD Graphics也就是GT2中只有一个Slice,而对于Iris系列中的GT3则有两个Slice;GT3e相对于GT3增加了eDRAM使其具有更快的内存访问速度,而GT4e则增加到三个Slice。GPU的基础功能模块主要由EU以及相关的Media Processing(MFX)等组成。一个Slice中有三个Sub-Slice,Sub-Slice中包含具体的EU和Media Sampler模块作为最基本的可编程处理单元,GPU相关的任务都是在EU上进行。而Media Processing中还集成了一个被称为MFX的独立模块,主要由Media Format Codec(MFX)与VQE组成。MFX可将一些处理任务通过Fix Function打包,固定于一个执行单元中进行统一的编解码处理,不调用EU从而实现提高EU处理3D图形等任务的速度。Video Quality Engine(VQE)提供De-interlace与De-Noise等视频处理任务,在编解码中使用EU是为了得到更高的视频编码质量。


1.3 结构演进


640?wx_fmt=png


上图展示的是英特尔几代核芯显卡产品在结构上的变化。最早的Haswell架构也就是v3系列中的EU个数相对较少,最多为40个;而到Broadwell架构的GT3中集成了2个Slice,EU个数随之增加到48个,图像处理性能也随之增强。从Broadwell架构发展到Skylake架构,除了EU与Slice格式增加的变化,MFX的组织也有相应改进。Broadwell架构是将MFX集成于一个Slice中,一个Slice集成一个MFX;而到Skylake架构之后Slice的个数增加了但MFX的个数并没有,此时的MFC便集成在Slice之外。随着组织方式的改变,核芯显卡的功能也随之改变:Skylake增加了HEVC的Decoder、PAK增加了基于HEVC的处理功能等改进为核芯显卡整体处理性能带来了显著提升,第六代以后的核芯显卡也都主要沿用GT3的架构组织。


640?wx_fmt=png


上文介绍了核芯显卡硬件上的模块结构,接下来我将具体介绍Quick Sync Video Acceleration。从Driver分发下来的Command Stream回通过多条路径在GPU上得到执行:如果命令属于编解码的Fix Function则会由MFX执行,部分与视频处理相关的命令会由VQE执行,其他的命令则会由EU执行。而编码过程主要分为两部分:ENC与PAK。ENC主要通过硬件实现Rate Control、Motion Estimation、Intra Prediction、Mode Decision等功能;PAK进行Motion Comp、Intra Prediction、Forward Quant、Pixel Reconstruction、Entropy Coding等功能。在目前的英特尔架构中,Media SDK通过API对硬件进行统一的调度与使用,同时我们提供更底层的接口Flexible Encoder Interface(FEI)以实现更优秀的底层调度与更好的处理效果。


2、软件策略


640?wx_fmt=png


接下来我将介绍英特尔的软件策略。最底层的FFmpeg可允许开发者将QSV集成进FFmpeg中以便于开发,而Media SDK则主要被用于编解码处理,FFmpeg可把整个多媒体处理有效结合。如果开发者认为传统的Media SDK的处理质量无法达到要求或码率控制不符合某些特定场景,那么可以通过调用FEI等更底层的接口对控制算法进行优化;最顶层的OpenCL接口则利用GPU功能实现边缘计算等处理任务,常见的Hybrid编码方式便使用了OpenCL。除此之外OpenCL也可实现一些其他的并行处理功能,例如与AI相关的一些计算。


2.1 Media SDK


640?wx_fmt=png


Media SDK分为以下几个版本:Community Edition是一个包含了基本功能的部分免费版本,Essential Edition与Professional Edition则是具有更多功能的收费版本,可实现例如hybrid HEVC 编码,Audio的编解码、Video Quality Caliper Tool等诸多高级功能和分析工具的集合。


1)软件架构


640?wx_fmt=png


上图主要介绍的是Media Server Studio Software Stack软件架构,我们基于此架构实现FFmpeg的加速。


这里需要强调的是:


a)OpenGL (mesa)与linux内核一直是开源的项目,但之前版本的MSS中存在一些私有的内核补丁,并对操作系统的或对Linux的内核版本有特殊要求。


b)HD Graphics Driver for Linux之前是一个闭源的方案,而现在的MSDK 和用户态驱动(iHD驱动)都已经实现开源。现在我们正在制作一个基于开源版本的Release,未来大家可以通过此开源平台获得更好的技术支持。


2)编解码支持


640?wx_fmt=png


关于编解码支持,其中我想强调的是HEVC 8 bit 与10 bit的编解码。在Gen 9也就是Skylake上并不支持硬件级别的HEVC 10 bit解码,面对这种情况我们可以通过混合模式实现对HEVC 10 bit的编解码功能。最新E3v6(Kabylake)虽然只有较低性能的GPU配置,但可以支持HEVC 10 bit解码,HEVC 10 bit编码功能则会在以后发布的芯片中提供。


2.2 QSV到FFmpeg的集成思路


640?wx_fmt=png


FFmpeg集成的思路主要如下:


1)FFmpeg QSV Plugins:将SDK作为FFmpeg的一部分进行封装,其中包括Decoder、Encoder与VPP Filter处理。


2)VAPPI Plugin:Media对整个英特尔GPU的软件架构而言,从最底层的linux内核,中间有用户态驱动,对外的统一的接口就是VAAPI。Media SDK的硬件加速就是基于VAAPI开发,同时增加了很多相关的功能,其代码更为复杂;而现在增加的VAAPI Plugin则会直接调用LibAV使软硬件结合更为紧密。


640?wx_fmt=png


接下来我将介绍如何将SDK集成到FFmpeg中,一共分为AVDecoder、AVEncoder、AVFilter三个部分。


1)AVFilter


AVFilter主要是利用硬件的GPU实现Video Processor功能,其中包括vpp_qsv、overlay_qsv、hwupload_qsv,其中我们重点开发了overlay_qsv,vpp_qsv与hwupload_qsv。 如果在一个视频处理的pipeline中有多个VPP的实例运行,会对性能造成很大的影响。我们的方案是实现一个大的VPP Filter中集成所有功能并通过设置参数实现调用,避免了多个VPP的实例存在。但是为什么将vpp_qsv与overlay_qsv分开?这是因为无法在一个VPP实例中同时完成compositor和一些视频处理功能(像de-interlace等)。英特尔核芯显卡内显存中的存储格式为NV12, 和非硬件加速的模块联合工作时,需要对Frame Buffer进行从系统内存到显卡显存的复制过程,hwupload_qsv提供了在系统内存和显卡内存之间进行快速帧转换的功能。


2)AVEncoder


AVEncoder目前支持H264、HEVC、MPEG-2等解码的硬件加速。


3)AVDecoder 


AVDecoder目前支持H264、HEVC、MPEG-2等协议的硬件加速。


最理想的方案是在整条视频处理的Pipeline中都使用显卡内存从而不存在内存之间的帧拷贝,从而达到最快的处理速度,但在实际应用中我们很多时候是做不到这一点。将MSDK集成进FFmpeg中时需要解决内存转换的问题,例如VPP Filter不支持一些功能或原始码流并不在Decoder支持的列表中。上图中粉色与绿色的转换表示的就是数据从显存到系统内存再到显存之间的转换。我们在实践中经常会遇到处理性能的急剧变化,可能的原因就是一些非硬件处理的模块和硬件加速的模块存在与同一个pipeline中,从而对整体性能造成影响。这是因为进行了额外的内存拷贝过程,一旦优化不足则会极大影响性能。具体进行内存分配时我们使用了hwcontext,这是FFmpeg在3.0之后增加的一个功能。我们基于FFmpeg中hwcontext的机制实现了hwcontext_qsv,从而对硬件的初始化与内存分配进行很好的管理。


3、对比MSS与FFmpeg+QSV


640?wx_fmt=png


下面我将分享MSS与FFmpeg+QSV的异同。二者支持相同的编解码器与视频处理。


二者的差异有:


1)MSS 仅提供了一套库和工具,用户必须基于 MSS进行二次开发;而FFmpeg 是一个流行的多媒体开放框架, QSV的GPU加速只是其中的一部分。


2)MSS的库中提供 了VPP 接口,用户要实现某些功能必须进行二次开发。而目前,FFmpeg+QSV已存在2个开发好的Filter,并且在Filter中集成了MSS 支持的所有功能,并提供更加简单的选项进行配置,这些功能对用户而言都是方便使用的。


3)在内存管理上,MSS的开发人员必须管理自己的内存;而FFmpeg 提供基本的内存管理单元并实现系统内存的统一调用,集成了硬件级别的内存处理机制。


4) FFmpeg 提供了一定的容错机制与 a/v 同步机制;FFmpeg+QSV 模块充分利用这些机制来提高兼容性,像使用ffmpeg的parse工具进行视频流预处理。


5)处理流程上,MSS的用户在使用MSS模块之前必须自己开发Mux/Demux或其他必要的模块;而FFmpeg+QSV 由于是基于 MSS 实现并添加了特殊的逻辑, 每个模块都可与 FFmpeg 的其他模块一起工作。


可以说FFmpeg有很强大的媒体支持,相对于传统的MSS在保证性能与质量的前提下为用户节省很多工作量并显著提升开发效率。


4、实践与测试


640?wx_fmt=png


上图展示的是我们在Skylake也就是Gen 9上测试硬件转码能力的结果。GT2、GT31、GT41三个型号性能递增;TU1、TU2、TU4、TU7表示编解码性能与图像质量的均衡程度,其中TU7表示最快的处理速度和较差的图像质量,TU1表示基于大量计算得到的较高图像质量。


640?wx_fmt=png


上图展示的是Skylake对HEVC支持的性能数据,其中的分辨率为1080P,其实HEVC 4K60p也能得到很好的性能。随着输出图像质量的提升,转码速度也会相应降低,但在正常使用中我们主要根据需求平衡性能与质量,在较短时间内实现较高质量的转码输出。


640?wx_fmt=png


如果重点分析图像质量,在实践中我们建议使用Medium模式得到相对较优的性能与质量。随着参数的变化,PSNR与图像的整体细节会出现较明显变化。


640?wx_fmt=png


Source Code主要有以下两种途径:可以从FFmpeg上直接clone,也可以访问Intel的Github获得相应源代码。Intel的github上的分支中的FFmpeg qsv模块是经过Intel的测试,相对而言问题更少运行更加稳定,大家也可以在Intel的Github上提出相关问题,我们会对部分问题进行解答。

 

640?wx_fmt=png640?wx_fmt=png640?wx_fmt=png640?wx_fmt=png


上图展示的是实践中可能需要的一些使用命令参考,其中我想强调的是Overlay Filter,在这里我们支持多种模式,包括插入台标的、电视墙等,也可在视频会议等场景中实现人工指定确定画面中每一个图片的位置等效果。



640?wx_fmt=jpeg

相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
相关文章
|
7月前
|
Web App开发 编解码 安全
视频会议技术 入门探究:WebRTC、Qt与FFmpeg在视频编解码中的应用
视频会议技术 入门探究:WebRTC、Qt与FFmpeg在视频编解码中的应用
699 4
|
7月前
|
存储 缓存 编解码
【FFmpeg 视频播放】深入理解多媒体播放:同步策略、缓冲技术与性能优化(一)
【FFmpeg 视频播放】深入理解多媒体播放:同步策略、缓冲技术与性能优化
373 0
|
7月前
|
存储 编解码 vr&ar
用C++实现视频编码器:FFmpeg与SDL技术结合,轻松编写高效编解码器
用C++实现视频编码器:FFmpeg与SDL技术结合,轻松编写高效编解码器
852 0
|
3月前
|
编解码 移动开发 安全
FFmpeg开发笔记(五十)聊聊几种流媒体传输技术的前世今生
自互联网普及以来,流媒体技术特别是视频直播技术不断进步,出现了多种传输协议。早期的MMS由微软主导,但随WMV格式衰落而减少使用。RTSP由网景和RealNetworks联合提出,支持多种格式,但在某些现代应用中不再受支持。RTMP由Adobe开发,曾广泛用于网络直播,但因HTML5不支持Flash而受影响。HLS由苹果开发,基于HTTP,适用于点播。SRT和RIST均为较新协议,强调安全与可靠性,尤其SRT在电视直播中应用增多。尽管RTMP仍占一定市场,但SRT等新协议正逐渐兴起。
128 8
FFmpeg开发笔记(五十)聊聊几种流媒体传输技术的前世今生
|
4月前
|
JavaScript 前端开发 Java
FFmpeg开发笔记(四十七)寒冬下安卓程序员的几个技术转型发展方向
IT寒冬使APP开发门槛提升,安卓程序员需转型。选项包括:深化Android开发,跟进Google新技术如Kotlin、Jetpack、Flutter及Compose;研究Android底层框架,掌握AOSP;转型Java后端开发,学习Spring Boot等框架;拓展大前端技能,掌握JavaScript、Node.js、Vue.js及特定框架如微信小程序、HarmonyOS;或转向C/C++底层开发,通过音视频项目如FFmpeg积累经验。每条路径都有相应的书籍和技术栈推荐,助你顺利过渡。
127 3
FFmpeg开发笔记(四十七)寒冬下安卓程序员的几个技术转型发展方向
|
7月前
|
Web App开发 编解码 vr&ar
使用FFmpeg从音视频处理到流媒体技术的探索和实战应用
使用FFmpeg从音视频处理到流媒体技术的探索和实战应用
312 2
|
7月前
|
存储 算法 C++
【FFmpeg 视频播放】深入理解多媒体播放:同步策略、缓冲技术与性能优化(二)
【FFmpeg 视频播放】深入理解多媒体播放:同步策略、缓冲技术与性能优化
335 0
|
2月前
|
Linux 开发工具 Android开发
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
ijkplayer是由Bilibili基于FFmpeg3.4研发并开源的播放器,适用于Android和iOS,支持本地视频及网络流媒体播放。本文详细介绍如何在新版Android Studio中导入并使用ijkplayer库,包括Gradle版本及配置更新、导入编译好的so文件以及添加直播链接播放代码等步骤,帮助开发者顺利进行App调试与开发。更多FFmpeg开发知识可参考《FFmpeg开发实战:从零基础到短视频上线》。
240 2
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
|
2月前
|
编解码 语音技术 内存技术
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
《FFmpeg开发实战:从零基础到短视频上线》一书中的“5.1.2 把音频流保存为PCM文件”章节介绍了将媒体文件中的音频流转换为原始PCM音频的方法。示例代码直接保存解码后的PCM数据,保留了原始音频的采样频率、声道数量和采样位数。但在实际应用中,有时需要特定规格的PCM音频。例如,某些语音识别引擎仅接受16位PCM数据,而标准MP3音频通常采用32位采样,因此需将32位MP3音频转换为16位PCM音频。
91 0
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
|
2月前
|
XML 开发工具 Android开发
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
ExoPlayer最初是为了解决Android早期MediaPlayer控件对网络视频兼容性差的问题而推出的。现在,Android官方已将其升级并纳入Jetpack的Media3库,使其成为音视频操作的统一引擎。新版ExoPlayer支持多种协议,解决了设备和系统碎片化问题,可在整个Android生态中一致运行。通过修改`build.gradle`文件、布局文件及Activity代码,并添加必要的权限,即可集成并使用ExoPlayer进行网络视频播放。具体步骤包括引入依赖库、配置播放界面、编写播放逻辑以及添加互联网访问权限。
191 1
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频