1. 程式人生 > >【ARM-Linux開發】【CUDA開發】【視訊開發】關於Linux下利用GPU對視訊進行硬體加速轉碼的方案

【ARM-Linux開發】【CUDA開發】【視訊開發】關於Linux下利用GPU對視訊進行硬體加速轉碼的方案

最近一直在研究Linux下利用GPU進行硬體加速轉碼的方案,折騰了很久,至今沒有找到比較理想的硬加速轉碼方案。似乎網上討論這一方案的文章也特別少,這個過程中也進行了各種嘗試,遇到很多具體問題,以下便對之前所作的一些工作做一些總結和分享,省的時間長了自己也忘記了,也希望後來者能少走彎路,並找到適合自己的最佳方案。

背景:

專案需要在指定的linux伺服器上對視訊源進行轉碼儲存,以節省儲存空間。作業系統必須是Linux,用來硬加速轉碼的GPU是nViDIA的GT440。

方案1:

由於nViDIA的CUDA SDK中提供了現成的硬加速encoder和decoder,最簡單、效能最有保障的方式就是呼叫CUDA中的編解碼API進行轉碼。國內比較有名的MediaCoder就是這麼搞的,當然它只用了CUDA的encoder,解碼還是用CPU來做的。但問題是,安裝了CUDA SDK之後才發現,CUDA提供的編解碼API只有windows的版本,沒有Linux的版本。於是,只能退而求其次地嘗試在Linux下安裝Windows虛擬機器試一下。

首先,試了一下Wine,安裝好Wine之後,嘗試安裝N卡的windows驅動,提示如下錯誤:

接著,又嘗試了在VisualBox中安裝Windows,再安裝N卡驅動,提示找不到N卡硬體,如圖:

據說MediaCoder支援Linux的方式,就是讓MediaCoder在Wine下面執行的,但是不知道為什麼我的環境下連驅動都裝不上。所以方案1對我來說,基本上屬於死路一條。

方案2:

用ffmpeg進行轉碼。因為發現ffmpeg自帶了VDPAU和VAAPI的硬加速解碼模組,所以想是不是通過引數設定就可以讓ffmpeg通過GPU來硬加速解碼。但是ffmpeg的說明文件關於硬加速這塊的描述不是很清楚,只能自己結合網上的零星文章做參考,慢慢摸索前進。

首先,編譯ffmpeg,確認configure的時候它的幾個decoders(h264_vdpau,mpeg4_vdpau,...)和hwaccels(h264_vaapi,mpeg4_vaapi,...)都是enable的。但是編譯好ffmpeg之後,通過設定強制解碼codec,比如h264_vdpau,執行ffmpeg時,會報一個PIX_FMT_XXX的錯誤,意思是解碼之後的格式不對,不能繼續用於編碼。

然後,下載了mplayer-vaapi-20110127hwdecode-demos,經過各種磨難之後,終於都編譯通過。經過測試,發現它們都可以利用vdpau和vaapi進行硬加速解碼,於是認為ffmpeg也應該可以利用vdpau和vaapi進行硬加速解碼。但又折騰了很久,找了很多資料,最後終於在ffmpeg-user上看到一個老外給別人的回帖,明確說了ffmpeg不能用vdpau和vaapi來轉碼,ffmpeg提供vdpau和vaapi的硬加速decoder,目的是為了給類似mplayer的應用來進行硬加速的視訊播放,當時就崩潰了!!!

最後,硬加速decode不行,咱就整encode吧。網上找到一個用OpenCL來硬加速的x264版本,x264demo。又經歷了各種磨難,終於將它編譯通過並和ffmpeg整合在一起了,期間還修復了x264若干bug。但是最後測試的結果,令人大失所望。雖然使用OpenCL方式加速之後,確實比原版x264快了20%-30%,但問題是:一、轉出來的視訊根本沒法用,存在大面積的花屏,本人對H.264編碼的演算法不甚瞭解,故這個大bug只能先放著了;二、H.264的編碼演算法還是蠻複雜的,因此x264編碼的效率比普通的mpeg編碼慢了10倍左右。這樣的話,用x264+OpenCL的方式對我來說就完全沒有必要了。

方案3:

用VLC+VAAPI進行硬加速轉碼。因為VAAPI的機制是在各個廠家提供的driver層上進行了統一的介面封裝,對於N卡,其底層呼叫的是VDPAU,因此硬體加速僅限於解碼部分,編碼還是用的軟編碼。前面說到ffmpeg無法利用VDPAU進行轉碼,是因為VDPAU解碼出來的格式不是YUV的,我想VLC應該是對VDPAU解碼出來的東東進行了進一步的加工,然後進行的編碼。測試下來的結果顯示,VLC硬加速轉碼的時候確實用到了GPU,但實際轉碼的時間和CPU佔用率並未得到很大的改善。

方案4:

純硬體加速方案,即利用成熟的DSP晶片進行轉碼。該方案可以根據需要,將多塊硬編解碼晶片整合在一起,實現多路視訊的同編同解。好處是,利用成熟晶片,不用太關心編解碼的具體演算法,方案可大可小,甚至可以用來做雲轉碼。可問題是,該方案不符合我的專案需求,哎,只能先放一放了。