1. 程式人生 > >英偉達硬體加速編解碼

英偉達硬體加速編解碼

硬體加速

硬體加速的學術名稱是 GPGPU(General-purpose computing on graphicsprocessing units),中文名稱是通用圖形處理器。最基本的思想是使用 GPU 的運算能力完成原本需要 CPU 來進行的運算。

平行計算

GPU 是用來處理圖形任務的圖形處理器,其中一個非常大的優勢在於它的並行處理能力。面對單指令流多資料流(SIMD),並且資料處理的運算量遠大於資料排程和傳輸的需要時,GPU 的並行處理效率要高於傳統的 CPU 的處理。

為了充分的利用 GPU 的並行處理能力,大部分的顯示卡廠商都推出了自己的 GPU 開發SDK,比如:

  • NVIDIA —— CUDA
  • Intel —— Intel® Media SDK
  • AMD —— AMD APP SDK(前身是 ATI Stream)

當然這些廠商都是各自為陣,推出的 SDK 都是隻能用於自己的顯示卡的 SDK,所以程式碼想要在不同的平臺上能夠統一是比較困難的。

OpenCL

OpenCL(Open Computing Language,開放計算語言),是一個為異構平臺編寫程式的框架,此異構平臺可由CPU,GPU或其他型別的處理器組成。這種語言主要是為了異構平臺的並行執行設計的。

從本質上來說,它和 CDUA 等等 SDK 上是不同的,它是一種語言,相當於是 JAVA語言這個級別,而後者是一個開發包,相當於 JDK 這個級別。

OpenCL 目前的語言規範已經到了 2.1(Preview),支援最好的 AMD 的 SDK,最新版本已經支援了 OpenCL 2.0,其他兩個只支援 OpenCL 1.2。

OpenCL 提供了一個統一的 API,這個 API 在上述的廠商的 SDK 中都有實現。所以安裝 CUDA 會包含 OpenCL 元件,它是英偉達對於 OpenCL 語言的一種實現。

OpenCL API VS SDK

OpenCL API 最大的優勢在於它的跨平臺,可以在不同的架構上執行,所以理論上它比 SDK 更有競爭力。但是它最大的問題在於它的 API Level 比較基礎,直接使用它進行視訊的編解碼處理難度比較大。

此外 OpenCL API 的實現是依賴於底層的 GPU 架構的,不同的廠商提供了不同的實現,使用之前需要安裝不同廠商提供的實現,從這個角度考慮 OpenCL 的跨平臺並沒有想象中那麼完美。

SDK 的問題在於不同的廠商的 SDK 是不相容的。但是它提供了比 OpenCL API 更加豐富的功能,比如 NVIDIA 直接提供了視訊編解碼相關的介面,使用起來會比OpenCL API 更加的輕鬆。

英偉達硬體編解碼方案

實現英偉達的 GPU 硬體編解碼可以使用如下幾種方案:

基於 OpenCL 的 API 自己寫一個編解碼器

這的難度非常大,首先你需要對於 OpenCL API 非常的熟悉,其次你需要對於編解碼的知識瞭解的非常透徹。這兩個問題的任何一個都有非常大的難度,以目前已有的技術來說成功的概念不是特別大。

MainConcept 公司做了這件事情,它提供了基於 OpenCL 的 H264/AVC 編碼器,但是這個編碼器是商用的(此外它還提供了基於 CUDA 的編碼器和基於 Intel QSV 的編解器,以及包裝過前面幾者的編碼器)。

所以從技術可行性上來說這個是可行的,只是目前來說個人還不具備這個實力。

使用 SDK 中的編解碼介面

英偉達關於視訊的編解碼提供了兩個相關的 SDK

  • NVENC
  • NVCUVID

前者負責硬體編碼,二後者負責硬體解碼。

NVENC 是一個單獨的 SDK,整合在最新的顯示卡驅動上面,安裝最新的驅動之後可以找到相關的庫檔案。在 Ubuntu 14.04 中,可以在 /usr/lib/nvidia-352/ 目錄下面找到相關的庫檔案。

NVCUVID 是 CUDA 的元件,包含在最新的 CUDA Toolkit 中。不過在顯示卡的類庫中可以找到 libnvcuvid.so 這個庫檔案。在之前版本的顯示卡驅動中其他還包含一個稱之為 NVCUVENC 的硬體編碼器和 NVCUVID 相對應,不過目前這個元件已經被 NVENC 替代了。

使用編碼器對於 OpenCL 和 SDK 的封裝

這種方式是個人認為最理想的方式,FFMPEG 目前存在一個編碼器 nvenc 是對於英偉達的 NVENC 的封裝,通過使用它可以和 FFMPEG 無縫的整合起來。此外它也包含對於 Intel QSV 的封裝。AMD 的相關介面目前沒有找到相關的資料。

不過 FFMPEG 只存在 NVENC 的介面,不存在 NVCUVID 的封裝。如果需要實現相關的解碼器可能需要自己實現 FFMPEG 介面。

libx264 有對於 OpenCL 的封裝,不過我在 windows 中嘗試這個功能的時候並沒有成功。

另外還存在一個開源的格式轉換器 HandBrake,它包含對於 Intel QuickSync的封裝,以及使用 OpenCL 進行圖象的拉伸處理和使用 x264 的 opencl封裝。這個專案缺點在於文件不是很豐富,研究起來有一定的難度。