英特爾QSV技術在FFmpeg中的實現與使用


本文來自英特爾資深軟件工程師張華在LiveVideoStackCon 2018講師熱身分享,並由LiveVideoStack整理而成。在分享中張華介紹了英特爾GPU硬件架構,並詳細解析了英特爾QSV技術在FFmpeg中的具體實現與使用。linux


文 / 張華git

整理 / LiveVideoStackgithub

直播回放:web

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


你們好,今天我與你們分享的是英特爾GPU架構以及Quick Sync Video技術在FFmpeg 中的實現與使用。編程


一、處理器總體架構微信



你們知道,英特爾的圖形處理GPU被稱爲「核芯顯卡」,與CPU集成封裝在同一個芯片上,上圖展現的是芯片的內部結構。session


1.1 發展架構



英特爾從lvy Bridge架構開始就嘗試將GPU與CPU集成在中央處理芯片中並逐代發展到Skylake架構。初期的Ivy Bridge架構中GPU所佔的面積很是小,而到如今的第五代處理器架構Skylake已經實現十分紅熟的GPU集成技術,GPU在芯片中所佔的面積已經超過了一半。在將來咱們將推出基於PCI-E的獨立顯卡,爲PC帶來更大的圖像性能提高。框架


1.2 基礎功能模塊



上圖展現的是一款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 結構演進



上圖展現的是英特爾幾代核芯顯卡產品在結構上的變化。最先的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的架構組織。



上文介紹了核芯顯卡硬件上的模塊結構,接下來我將具體介紹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)以實現更優秀的底層調度與更好的處理效果。


二、軟件策略



接下來我將介紹英特爾的軟件策略。最底層的FFmpeg可容許開發者將QSV集成進FFmpeg中以便於開發,而Media SDK則主要被用於編解碼處理,FFmpeg可把整個多媒體處理有效結合。若是開發者認爲傳統的Media SDK的處理質量沒法達到要求或碼率控制不符合某些特定場景,那麼能夠經過調用FEI等更底層的接口對控制算法進行優化;最頂層的OpenCL接口則利用GPU功能實現邊緣計算等處理任務,常見的Hybrid編碼方式便使用了OpenCL。除此以外OpenCL也可實現一些其餘的並行處理功能,例如與AI相關的一些計算。


2.1 Media SDK



Media SDK分爲如下幾個版本:Community Edition是一個包含了基本功能的部分免費版本,Essential Edition與Professional Edition則是具備更多功能的收費版本,可實現例如hybrid HEVC 編碼,Audio的編解碼、Video Quality Caliper Tool等諸多高級功能和分析工具的集合。


1)軟件架構



上圖主要介紹的是Media Server Studio Software Stack軟件架構,咱們基於此架構實現FFmpeg的加速。


這裏須要強調的是:


a)OpenGL (mesa)與linux內核一直是開源的項目,但以前版本的MSS中存在一些私有的內核補丁,並對操做系統的或對Linux的內核版本有特殊要求。


b)HD Graphics Driver for Linux以前是一個閉源的方案,而如今的MSDK 和用戶態驅動(iHD驅動)都已經實現開源。如今咱們正在製做一個基於開源版本的Release,將來你們能夠經過此開源平臺得到更好的技術支持。


2)編解碼支持



關於編解碼支持,其中我想強調的是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的集成思路



FFmpeg集成的思路主要以下:


1)FFmpeg QSV Plugins:將SDK做爲FFmpeg的一部分進行封裝,其中包括Decoder、Encoder與VPP Filter處理。


2)VAPPI Plugin:Media對整個英特爾GPU的軟件架構而言,從最底層的linux內核,中間有用戶態驅動,對外的統一的接口就是VAAPI。Media SDK的硬件加速就是基於VAAPI開發,同時增長了不少相關的功能,其代碼更爲複雜;而如今增長的VAAPI Plugin則會直接調用LibAV使軟硬件結合更爲緊密。



接下來我將介紹如何將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目前支持H26四、HEVC、MPEG-2等解碼的硬件加速。


3)AVDecoder 


AVDecoder目前支持H26四、HEVC、MPEG-2等協議的硬件加速。


最理想的方案是在整條視頻處理的Pipeline中都使用顯卡內存從而不存在內存之間的幀拷貝,從而達到最快的處理速度,但在實際應用中咱們不少時候是作不到這一點。將MSDK集成進FFmpeg中時須要解決內存轉換的問題,例如VPP Filter不支持一些功能或原始碼流並不在Decoder支持的列表中。上圖中粉色與綠色的轉換表示的就是數據從顯存到系統內存再到顯存之間的轉換。咱們在實踐中常常會遇處處理性能的急劇變化,可能的緣由就是一些非硬件處理的模塊和硬件加速的模塊存在與同一個pipeline中,從而對總體性能形成影響。這是由於進行了額外的內存拷貝過程,一旦優化不足則會極大影響性能。具體進行內存分配時咱們使用了hwcontext,這是FFmpeg在3.0以後增長的一個功能。咱們基於FFmpeg中hwcontext的機制實現了hwcontext_qsv,從而對硬件的初始化與內存分配進行很好的管理。


三、對比MSS與FFmpeg+QSV



下面我將分享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在保證性能與質量的前提下爲用戶節省不少工做量並顯著提高開發效率。


四、實踐與測試



上圖展現的是咱們在Skylake也就是Gen 9上測試硬件轉碼能力的結果。GT二、GT3一、GT41三個型號性能遞增;TU一、TU二、TU四、TU7表示編解碼性能與圖像質量的均衡程度,其中TU7表示最快的處理速度和較差的圖像質量,TU1表示基於大量計算獲得的較高圖像質量。



上圖展現的是Skylake對HEVC支持的性能數據,其中的分辨率爲1080P,其實HEVC 4K60p也能獲得很好的性能。隨着輸出圖像質量的提高,轉碼速度也會相應下降,但在正常使用中咱們主要根據需求平衡性能與質量,在較短期內實現較高質量的轉碼輸出。



若是重點分析圖像質量,在實踐中咱們建議使用Medium模式獲得相對較優的性能與質量。隨着參數的變化,PSNR與圖像的總體細節會出現較明顯變化。



Source Code主要有如下兩種途徑:能夠從FFmpeg上直接clone,也能夠訪問Intel的Github得到相應源代碼。Intel的github上的分支中的FFmpeg qsv模塊是通過Intel的測試,相對而言問題更少運行更加穩定,你們也能夠在Intel的Github上提出相關問題,咱們會對部分問題進行解答。

 


上圖展現的是實踐中可能須要的一些使用命令參考,其中我想強調的是Overlay Filter,在這裏咱們支持多種模式,包括插入臺標的、電視牆等,也可在視頻會議等場景中實現人工指定肯定畫面中每個圖片的位置等效果。



本文分享自微信公衆號 - LiveVideoStack(livevideostack)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索