1. 程式人生 > >使用GPU加速H.264編碼分析

使用GPU加速H.264編碼分析

繼前面的“GPGPU”和“CUDA和OpenCL”的簡介後,接下來分析一個具體的使用案例:是否可以用GPU搭建一個高效能的H.264編解碼伺服器?

設想一個簡單的需求:

  1. 把其他編碼的視訊轉換為指定位元速率的H.264;
  2. 在轉換過程中做一些簡單的處理(例如增刪水印、字幕的處理、聲音的處理等);
  3. 需要封裝成指定的一種container格式,比如mp4或mkv。

ffmpeg完成此項工作的大概過程是:

  1. 識別檔案格式,開啟視訊檔案容器,得到video_stream;
  2. 使用libavcodec把video_stream解碼成原始的frame資料;
  3. 在frame的基礎上做“需求2”的處理;
  4. 編碼成H.264格式;
  5. 存放到指定格式的容器中(mp4或者mkv)。

“過程1”應該是一個輕量操作,且對於現有視訊格式速度應該很快(播放器看片的時候不可能先等上幾秒分析一把格式再開始播放吧?)。

“過程2”需要把原有的視訊編碼解碼並轉為ffmpeg內部使用的格式,速度會比上第一步慢不少,但是應該也是可以接受的。當然在位元速率比較高的情況下也會非常緩慢(在Pentium4時代的機器上看1080p的高清視訊很卡)。

“過程3”是需要對每一幀進行處理,那麼這步是可高度並行化的應該可以放到GPU進行。

“過程4”一定是最慢的一個環節:H.264需要將影象分割成很多個巨集塊, 然後利用視訊幀影象的幀內和幀間的相關性, 採用幀內預測或幀間預測的編碼模式, 對各個巨集塊進行壓縮。然後形成幀,組成為碼流。整個過程複雜,但巨集塊兒的處理是可以高度並行化的操作,應該可以放到GPU進行。

“過程5”和“過程1”類似。

所以如果想用GPU加速以上的過程,那麼把“過程4”和“過程2”的密集計算從CPU上轉到GPU上,應該是可能的發力點。

如果要設計這個系統,軟體自底層到上層有幾點需要考慮:

  1. 如果顯示卡可以指定,應該是Nvidia。在Linux下有完善的開發執行環境,且同時支援CUDA和OpenCL;
  2. 如果選定Nvidia顯示卡,那麼根據前文的分析,使用CUDA是更好的GPU計算架構。並且應該使用最新的CUDA 4.0版本,因為在多GPU上能更方便的開發,並且GPU直接訪問記憶體方面也做出了改進(CUDA 4.0的新特性詳細見這裡)。
  3. 在決定了以上基礎設施後,為了提高單機的處理能力程式應該用何種架構來編寫?單程序多執行緒還是多程序單執行緒?

關鍵在於在程式裡如何更好的呼叫CUDA:

  1. 單程序多執行緒方式
    • 每個執行緒進行一個視訊的轉換,每個執行緒在其執行緒內部直接使用CUDA;
    • 有單獨的CUDA執行緒,其他執行緒當需要時通知此執行緒進行運算;
  2. 多程序單執行緒
    • 每個程序進行一個視訊的轉換,在其程序內部各自獨立的使用CUDA;
    • 有單獨的GPU程序,其他程序當需要進行GPU運算的時IPC通知此程序進行;

在我看來,2-1的方式是最簡單直接的,可以直接基於ffmpeg來實現,只需單把可並行化的部分從CPU移到GPU。但是CUDA 4.0是否支援這樣做?這樣做效率是否最高?

硬體配置上也有以下的問題:

  1. 是否需要在一個Server上配置多塊兒GPU?雖說CUDA 4.0已經聲稱對此有很好的支援,但是其是否能利用好?另外受限於硬體瓶頸的一些限制(CPU計算能力、記憶體速度、匯流排速度),配置幾塊兒GPU比較合適?
  2. 如果使用ffmpeg,那麼在一臺擁有16核的伺服器上,理論可以同時啟動16個ffmpeg程序(單執行緒執行)。加入GPU運算後單個視訊處理速度的提高是一定的,但是否還有這麼大的並行能力?以及單位時間段內的處理能力是否提升?
  3. 加入GPU後硬體成本的增加是否值得?與單獨使用CPU的相比單位成本是否更低?選用哪款Nvidia顯示卡的價效比最高?
  4. 如何看GPU的load average和top?

最後這件事情最難的一點在於:需要對CUDA、ffmpeg、H.264、硬體都有相當深入的瞭解才能做好這樣的一個系統

http://www.qingran.net/2011/07/%E4%BD%BF%E7%94%A8gpu%E5%8A%A0%E9%80%9Fh-264%E7%BC%96%E7%A0%81%E5%88%86%E6%9E%90/