FFmpeg簡介
被稱為「多媒體技術領域的瑞士軍刀」,FFmpeg擁有廣泛的應用基礎。不過,當(實時)處理海量視頻時,需要藉助各種方法提升效率。比如,短視頻平臺Revvel將視頻轉碼服務遷移到AWS Lambda和S3上,節省了大量費用和運維成本,並且將時長2小時的視頻轉碼從4-6小時縮短到不到10分鐘。
多媒體應用程序是典型的資源密集型應用,因此優化多媒體應用程序至關重要,這也是使用視頻處理專用硬體加速的初衷。作為回報,這允許整個系統更加有效地運行(以達到最佳性能)。 但是為了支持硬體加速,軟體開發廠商面臨著各種挑戰:一個是存在潛在的系統性能風險問題;此外,軟體開發商一直也因為要面對各種硬體架構的複雜性而苦苦掙扎,並需要維護不同的代碼路徑來支持不同的架構和不同的方案。優化這類代碼,耗時費力。想想你可能需要面對不同的操作系統,諸如Linux,Windows,macOS,Android,iOS,ChromeOS;需要面對不同的硬體廠商,諸如Intel,NVIDIA,AMD,ARM,TI, Broadcom……,因此,提供一個通用且完整的跨平臺,跨硬體廠商的多媒體硬體加速方案顯得價值非凡。
專用視頻加速硬體可以使得解碼,編碼或過濾(Filter)等操作更快完成且使用更少的其他資源(特別是CPU),但可能會存在額外的限制,而這些限制在僅使用軟體CODEC時一般不存在。在PC平臺上,視頻硬體通常集成到GPU(來自AMD,Intel或NVIDIA)中,而在移動SoC類型的平臺上,它通常是獨立的IP核(存在著許多不同的供應商)。硬體解碼器一般生成與軟體解碼器相同的輸出,但使用更少的Power和CPU來完成解碼。另外,各種硬體支持的Feature也各不相同。對於具有多種不同Profile的複雜的CODEC,硬體解碼器很少實現全部功能(例如,對於H.264,硬體解碼器往往只支持8bit的YUV 4:2:0)。
許多硬體解碼器的一個共同特點是能夠輸出硬體Surface,而該Surface可以被其他組件進一步使用(使用獨立顯卡時,這意味著硬體Surface在GPU的存儲器中,而非系統內存) ,對於播放(Playback)的場景,避免了渲染輸出之前的Copy操作;在某些情況下,它也可以與支持硬體Surface輸入的編碼器一起使用,以避免在轉碼(transcode)情況下進行任何Copy操作。另外,通常認為硬體編碼器的輸出比x264等優秀軟體編碼器質量差一些,但速度通常更快,且不會佔用太多的CPU資源。也就是說,他們需要更高的比特率來使輸出相同的視覺感知質量,或者他們以相同的比特率以更低的視覺感知質量輸出。具有解碼和/或編碼能力的系統還可以提供其他相關過濾(Filter)功能,比如常見的縮放(scale)和去隔行(deinterlace);其他後處理(postprocessing)功能可能取決於系統。
FFmpeg所支持的硬體加速方案,粗略以各OS廠商和Chip廠商特定方案以及行業聯盟定義的標準來分為3類;其中,OS涉及Windows,Linux,macOS,Android;Chip廠商的特定方案涉及到Intel,AMD,Nvidia等;而行業標準則著重OpenMAX與OpenCL ;這只是一個粗略的分類,很多時候,這幾者之間縱橫交錯,聯繫繁雜,之間的關係並非像列出的3類這般涇渭分明;這從另一個側面也印證了硬體加速方案的複雜性。就像我們熟知的大部分事情一樣,各種API或解決方案一面在不斷的進化同時,它們也背負著過去的歷史,後面的分析中也可以或多或少的窺知其變遷的痕跡。
1.基於OS的硬體加速方案
- Windows:Direct3D 9 DXVA2 /Direct3D 11 Video API/DirectShow /Media Foundation
大多數用於Windows 上的多媒體應用程序都基於Microsoft DirectShow 或Microsoft Media Foundation(MF)框架API,用他們去支持處理媒體文件的各種操作;而Microsoft DirectShow Plug in和Microsoft Foundation Transforms(MFT)均集成了Microsoft DirectX 視頻加速(DXVA)2.0,允許調用標準 DXVA 2.0 介面直接操作GPU去offload Video的負載(workload)。
DirectX視頻加速(DXVA)是一個API和以及需要一個對應的DDI實現,它被用作硬體加速視頻處理。軟體CODEC和軟體視頻處理器可以使用DXVA將某些CPU密集型操作卸載到GPU。例如,軟體解碼器可以將逆離散餘弦變換(iDCT)卸載到GPU。 在DXVA中,一些解碼操作由圖形硬體驅動程序實現,這組功能被稱為加速器( accelerator);其他解碼操作由用戶模式應用軟體實現,稱為主機解碼器或軟體解碼器。通常情況下,加速器使用GPU來加速某些操作。無論何時加速器執行解碼操作,主機解碼器都必須將包含執行操作所需信息的加速器緩衝區傳送給加速器緩衝區。
DXVA 2 API需要Windows Vista或更高版本。為了後向兼容,Windows Vista仍支持DXVA 1 API(Windows提供了一個模擬層,可在API和DDI的版本之間進行轉換;另外,由於 DAVX 1現在存在的價值基本上是後向兼容,所以我們略過它,文章中的DXVA,大多數情況下指的實際上是 DAVA2)。為了使用 DXVA功能,基本上只能根據需要選擇使用DirectShow或者Media Foundation;另外,需要注意的是,DXVA/DXVA2/DXVA-HD只定義瞭解碼加速,後處理加速,並未定義編碼加速,如果想從Windows層面加速編碼的話,只能選擇Media Foundation或者特定Chip廠商的編碼加速實現。現在,FFmpeg只支持了DXVA2的硬體加速解碼,DXVA-HD加速的後處理和基於Media Foundation硬體加速的編碼並未支持(在DirectShow時代,Windows上的編碼支持需要使用FSDK)。
下圖展示了基於Media Foundation媒體框架下,支持硬體加速的轉碼情況下的Pipeline: