被稱為“多媒體技術領域的瑞士軍刀”,FFmpeg擁有廣泛的應用基礎。不過,當(實時)處理海量視頻時,需要借助各種方法提升效率。比如,短視頻平臺Revvel將視頻轉碼服務遷移到AWS Lambda和S3上,節省了大量費用和運維成本,并且將時長2小時的視頻轉碼從4-6小時縮短到不到10分鐘。本文將縱覽FFmpeg的硬件加速方案,涉及各主流硬件方案和操作系統。本文為此系列的下篇,上篇請訪問這里。感謝英特爾資深軟件開發工程師趙軍的投稿。
文 / 趙軍
Android: MediaCodec
MediaCodec是Google在Android API 16之后推出的用于音視頻編解碼的一套偏底層的API,可以直接利用硬件以加速視頻的編解碼處理。MediaCodec的概念中,一般而言,編解碼器處理輸入數據并生成輸出數據。它異步處理數據并使用一組輸入和輸出緩沖區。在簡單的層面上,需要請求(或接收)一個空輸入緩沖區,填充數據并將其發送到編解碼器進行處理。編解碼器使用數據并將其轉換為其空的輸出緩沖區之一。最后,你請求(或接收)一個填充的輸出緩沖區,消耗其內容并將其釋放回編解碼器。
MediaCodec可以處理的數據有以下三種類型:被壓縮的Buffer(Compressed Buffers)、原始音頻數據(Raw Audio Buffers)、原始視頻數據(Raw Video Buffers)。可以使用ByteBuffers處理所有三種數據,但一般應該使用Surface以提高編解碼器的性能。 Surface使用本地視頻緩沖區,無需映射或復制到ByteBuffers; 因此,效率更高。 通常在使用Surface時無法訪問原始視頻數據,但可以使用ImageReader類來訪問不安全的解碼(原始)視頻幀。 這可能比使用ByteBuffers更有效率,因為一些本機緩沖區可能被直接映射到ByteBuffers。 當使用ByteBuffer模式時,也可以使用Image類和getInput / OutputImage(int)訪問原始視頻幀。FFmpeg自3.1版本加入了android MediaCodec硬件解碼支持,其實現Follow了FFmpeg的HWaccel接口,但直到現在為止,FFmpeg都并未支持基于MediaCodec的硬件加速編碼。
1.基于Chip 廠商的私有方案
這里所提及的私有,并非是說代碼沒有Open,更多層面上是指所提供的相應的API接口和實現,是廠商所特定的,而非行業標準定義的API ,諸如OpenMAX或者OS層面剝離了硬件具體實現相關抽象的API。更進一步說,是采用相關廠商私有方案之后,如果想要二次深度開發,其困難度較大一些。實際上,從開放的角度而言,Intel,AMD,Nvidia這3家GPU大廠所提供的方案的Open 程度不盡相同,總的說來,其開放程度是Intel好于AMD, 而AMD又好于Nvidia。
Intel: Media SDK:
Intel提供的Media SDK,本質是一套跨平臺的加速方案,它在Windows/Linux上提供了相同的API,底層則分別使用了Windows上的DXVA2和Linux上的VAAPI接口,以Windows平臺上為例,它的基本結構框圖如下:
而在FFmpeg的集成中,基本上是在Libavcode/Libavfilter內提供了一個基本的wrapper去調用Media SDK的API來提供相應的功能。下圖展示了Libavcodec集成MediaSDK的h264/hevc/mpeg2 Codec的狀態,需要注意的是,FFmpeg master開發分支上支持的FFmpeg QSV已經支持了更多的Codec和相關VPP功能。
在Windows平臺,如果你想在Intel 平臺上執行編碼相關的事務, Media SDK基本上是唯一的選擇。當然,如果你更偏向FFmpeg的API,可以使用FFmpeg QSV/Media SDK的方式;而在Linux平臺,FFmpeg VA-API與FFmpeg QSV/Media SDK 接口大部分功能重合,更多的區別可能在于軟件靈活度和開放程度的考量。一般說來,FFmpeg VA-API提供了更大的靈活度,對于有開發能力或者想二次定制的客戶更加的友好一些。從FFmpeg的角度看,這兩者在FFmpeg框架內的最大不同點在于: FFmpeg VA-API是以Native CODEC的方式直接實現與FFmpeg內部,而FFmpeg QSV集成Media SDK的方式,非嚴格的類比則類似于FFmpeg 集成libx264 這樣第三方庫的方式,需要依賴Media SDK,而FFmpeg VA-API則并不依賴第三方的庫,其CODEC的實現直接位于FFmpeg代碼庫自身。另外,需要提及的另外一件事情是,Media SDK開放了部分功能,其代碼Repo在:
https://github.com/Intel-Media-SDK/MediaSDK
Nvidia: CUDA/CUVID/NVENC
之前提及Nvidia的時候說過,Nvidia曾經一度提出VDPAU與Intel 提出的VA-API在Linux上競爭,但最近的趨勢似乎是Nvidia走向了更為封閉的方式,最主要的傾向是,Nvidia似乎放緩了對VPDAU的支持,取而代之的是提供較為封閉的NVDEC與NVENC庫。另外,在FFmpeg中集成NVENC 與NVDEC的方式與FFmpeg QSV集成Intel Media SDK方式一致,也是以集成第三方庫的方式集成進FFmpeg的。這帶來的弊端是,對NVENC/NVDEC的依賴較大,加上Nvidia并未開放NVENC/NVDEC的代碼,因此如果想做二次開發或者功能增強以及性能調整的時候,基本都得依賴Nvidia自身去改動NVENC/NVDEC,這可能對部分開發者帶來一些影響。
下面是NVECN/NVDEC說支持的CODEC的一個圖示,基本上FFmpeg CUVID/NVECN/CUDA部分分別集成了硬件加速的解碼,編碼以及部分CUDA加速的諸如Scaling這樣的Filter。另外,CUVID部分,為了和NVENC統一,Nvidia已經把它改稱為NVENC,但FFmpeg并沒有去做這個更新。
AMD: AMF
AMF SDK用于控制AMD媒體加速器,以進行視頻編碼和解碼以及色彩空間轉換,現在開源出來的版本(https://github.com/GPUOpen-LibrariesAndSDKs/AMF),并未支持Linux,只能在Windows上進行編碼,支持的Codec有AVC/HEVC。需要指出的是AMF的全稱是Advanced Media Framework,之前有時會被稱之為VCE(Video Coding Engine)
另外,VCE實際上支持兩種模式,一種模式是所謂的full fixed mode,這種模式之下,所有的編碼相關執行使用的ASIC 方式,而另一種模式則是hybrid mode,主要是通過GPU中的3D引擎的計算單元執行編碼相關動作,而對應的接口則是AMD's Accelerated Parallel Programming SDK 以及 OpenCL。
除了上述的一些方案以外,還有一些使用在嵌入式平臺的一些方案,能夠看到的有:
-
BRCM的MMAL:
http://www.jvcref.com/files/PI/documentation/html/
https://github.com/techyian/MMALSharp/wiki/What-is-MMAL%3F
-
RockChip:MPP
http://opensource.rock-chips.com/wiki_Mpp
http://opensource.rock-chips.com/images/f/fa/MPP_Development_Reference.pdf
-
TI DSP方案:
http://www.ti.com/processors/dsp/applications.html
有興趣者,可以通過這些資源自行去獲取相關信息。
2.獨立于平臺與Chip廠商的優化方案
OpenCL與Vulkan:
Khronos在OpenGL的年代一戰成名,最近這些年,圍繞著高性能圖形圖像API提出了大量的標準,其中有兩個較新的標準值得注意,一個是OpenCL,最初是Apple提出,現在則是異構高性能并行計算的標準,其出發點基本是以Nvidia的CUDA為對標;另一個則是OpenGL的后繼者Vulkan。最新的動向是Khronos似乎打算把OpenCL標準整合進Vulkan,所以很可能不久的將來,Vulkan會變成統一圖像與計算的API。由于OpenCL基本上是GPU上編程的唯一通用標準(另一個業內使用范圍更廣泛的是Nvidia的CUDA),很自然的FFmpeg也打算用OpenCL去加速相應的一些Codec或者AVfiter相關的任務。最初,x264嘗試用OpenCL優化,但結果并不盡理想,主要原因估計是很多時候編碼器實現是一個反復迭代的過程,數據之間也會出現依賴,導致想完全并發利用OpenCL去加速,比較困難,所以最終x264只用OpenCL加速了部分功能,更多的信息可以參考
https://mailman.videolan.org/pipermail/x264-devel/2013-April/009996.html
FFmpeg并未嘗試用OpenCL去優化Codec部分,但是卻優化了AVFilter部分,主要用在硬件加速轉碼的場景下。其最大的好處是解碼,Filter、編碼都在GPU內部完成,避免了GPU與CPU之間的數據交換,而一般Codec輸出的數據,需要與OpenCL實現所謂的Zero Copy,這一點,需要OpenCL做一些擴展以支持接收解碼器解碼的出來的數據格式,并輸出編碼器能接收的數據格式。這里典型的擴展如Intel 提出的OpenCL與VA-API的Surface sharing:
https://www.khronos.org/registry/OpenCL/extensions/intel/cl_intel_va_api_media_sharing.txt:
最近,FFmpeg社區的Rostislav Pehlivanov開始嘗試用Vulkan優化AVFilter,已經提交了Patch,正處于Review階段,從他FOSDEM的PPT https://pars.ee/slides/fosdem18_encoding.pdf 看,他似乎也想再次嘗試用Vulkan來優化Codec,但初期只有針對AVFilter的優化代碼出現。順帶說一句,Rostislav Pehlivanov的這份PPT中,回顧了各種CODEC上的各種嘗試,整個行業在CODEC上的努力,而其中大部分的CODEC,并未流行開來,但這些人的種種努力不該被完全忘記。
3.參考文獻
-
https://developer.nvidia.com/nvidia-video-codec-sdk 更多Nvidia video codec的信息,可以從這里獲取到
-
http://on-demand.gputechconf.com/gtc/2016/presentation/s6226-abhijit-patait-high-performance-video.pdf 這里對NVENC/NVDEC 給出了一些詳盡的說明
-
https://developer.android.com/reference/android/media/MediaCodec.html 使用MediaCodec時候,Android上的文檔基本上是必須要先讀的
-
https://elinux.org/images/9/9d/Android_media_framework--van-dam_and_kallere.pdf
-
https://static1.squarespace.com/static/4eb80772d09a941b5c45e0c0/t/541f2918e4b092469720191e/1411328280290/Video_DroidConNYC.pdf
-
https://www.khronos.org/ khronos 最近動作不斷,一方面,看到各種新標準的提出,另一方面又擔心這些標準最終實施的狀況。
WebRTCon 2018
WebRTCon 2018將于5月19-20日在上海光大國際會展中心舉行,這是一次對過去幾年WebRTC技術實踐與應用落地的總結。
大會組委會以行業難點為目標,設立了主題演講,WebRTC與前端,行業應用專場,測試監控和服務保障,娛樂多媒體開發應用實踐,WebRTC深度開發,解決方案專場,WebRTC服務端開發,新技術跨界,WebRTC與Codec等多個專場。邀請30余位全球領先的WebRTC技術專家,為參會者帶來全球同步的技術實踐與趨勢解讀。
在主題演講環節,Google軟件工程師Zoe Liu 、姜健,將分別向國內的開發者分享AV1的最新進展與技術探索、VP9的SVC優化。此外,北京大學教授王榮剛、英特爾實時通信客戶端架構師邱建林、Aupera傲睿智存 CTO周正寧將分別分享國產Codec AVS2的最新演進、H.264的硬件編碼優化,FPGA加速WebRTC服務端和轉碼。上海交通大學圖像通信與網絡工程研究所副所長宋利會分享學術界在Codec優化的最新思路與嘗試,他會介紹AI、區塊鏈和大數據賦能的Codec。
-
嵌入式
+關注
關注
5068文章
19017瀏覽量
303242 -
Android
+關注
關注
12文章
3923瀏覽量
127132 -
intel
+關注
關注
19文章
3480瀏覽量
185751
原文標題:FFmpeg 硬件加速方案概覽 (下)
文章出處:【微信號:livevideostack,微信公眾號:LiveVideoStack】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論