【GStreamer開發】GStreamer播放教程08——視頻解碼的硬件加速


目標

      視頻的硬件解碼近來發展非常快速,尤其是在低功耗的設備上。本教程會講述一些硬件加速的背景知識並解釋一下GStreamer是怎么做的。

      悄悄告訴你,如果設置正確地話,我們什么也不用做,GStreamer自動做完這一切的。


介紹

      視頻解碼是非常消耗CPU的一個任務,尤其是1080P這種高分辨率的高清節目。幸運的是,現在的顯卡都帶了可編程的GPU,如果我們用GPU用來做視頻解碼,那么CPU就可以解放出來做其他的任務了。低功耗的CPU是無法做解碼這樣的工作的,這時硬件的配合就是必須的了。

      目前來說(2012.07),每個GPU的制造商都提供了訪問它們的硬件的方法(API),不幸的是各家並不相同,並沒有一個強制的標准。

      VAAPI(Video Acceleration API):2007年Intel設計的,目的是在Unix操作系統的XWindow系統下運行,現在開源了。現在不僅僅局限於Intel的GPU了,其他制造商也可以使用了。GStreamer通過gstreamer-vaapi和fluvadec這個插件來使用。

      VDPAU(Video Decode and Presentation API for Unix):2008年NVidia設計的,最早也是運行在Unix的XWindow系統下,現在同樣開源了。雖然同樣已經是開源庫了,但除了NVidia自己外還沒有其他制造商使用。GStreamer通過vdpau和fluvadec這個插件來使用。

      DXVA(DirectX Video Acceleration):微軟為了Windows系統和XBox360定制的。GStreamer通過fluvadec這個插件來使用。

      XVBA(X-Video Bitstream Acceleration):AMD設計,在Linux操作系統的XWindow系統下下X Video的擴展。目前在AMD的ATI顯卡中有支持。GStreamer通過fluvadec這個插件來使用。

      VDA(Video Decode Acceleration):應用於Mac OSX10.6.3之后,僅僅加速H.264的解碼,GStreamer通過fluvadec這個插件來使用。

      OpenMAX(Open Media Acceleration):由非盈利性聯合Khronos Group設計的,是一組跨平台的C語言編程接口。GStreamer通過gstreamer-omx這個插件來使用。

      OVD(Open Video Decode):AMD的又一個API,GStreamer目前不能使用這個接口。

      DCE(Distributed Codec Engine):一個開源的軟件庫(libdce)和TI定制的API,提供給linux系統和ARM平台的。GStreamer通過gstreamer-ducati插件可以使用。


硬件加速視頻解碼插件內部的工作原理

      通常這些API提供了一系列的功能,比如:視頻解碼,后處理,解碼幀的描述,或者把幀下載到系統內存等等。相應的,不同的功能插件一般是給不同的element使用的,這樣pipeline可以適應任何需求。

      例如:gstreamer-vaapi這個插件提供了vaapidecode、vaapiupload、vaapidownload、vaapisink這些element,允許通過VAAPI來使用硬件加速功能,上傳原始視頻幀數據到GPU內存,下載GPU幀到系統內存並且描述GPU幀的內容。

      這里區分傳統的GStreamer幀(在系統內存中)和由硬件加速API生成的幀是很重要的。硬件加速生成的幀位於GPU的內存中,是GStreamer不能直接操作的。通常他們是下載到系統內存中,然后就可以被當成普通幀來處理了,但留在GPU中由GPU來顯示效率是最高的。

      GStreamer需要追蹤這些“硬件緩沖區”,因為這樣傳統的緩沖區可以繼續從一個element流向另一個element,但他們的內容盡皆是硬件緩沖區的ID或者Handler。比如:一個appsink獲得了硬件緩沖區ID,硬件緩沖區什么都不會響應,因為它們只能由生成它們的插件來處理。

      為了讓這個更加明確,這些緩沖區都有特殊的Caps,就像video/x-vdpau-output或者video/x-fluendo-va這樣。在這種方式下,GStreamer的自動插入機制不會試着把硬件緩沖區去傳給傳統的element——因為他們根本風馬牛不相及。而且,使用了這些Caps之后,自動插入機制就可以使用硬件加速來搭建pipeline了,因為,在VAAIP解碼器之后,只有VAAPI sink這一種element是可以連接上去的。

      這些都說明,如果一個硬件加速的API在系統中可用而且對應的GStreamer插件也有的話,playbin2等自動連接的element可用隨意的使用它們來搭建pipeline,應用不需要做什么特殊的處理。

      當playbin2必須在一些element中選擇時,就像是選擇傳統的軟件解碼還是硬件加速的解碼,它會使用rank來決定。這個rank屬性是每個element都有的,它會指明優先級,playbin2會選用最高的rank的element來搭建pipeline。

      所以,playbin2是否使用硬件加速的element取決於當時所有可用的element的rank值。而且,最簡單地確保硬件加速的element被選中的方法是修改rank屬性的值。代碼如下:

[objc] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. static void enable_factory (const gchar *name, gboolean enable) {  
  2.     GstRegistry *registry = NULL;  
  3.     GstElementFactory *factory = NULL;  
  4.        
  5.     registry = gst_registry_get_default ();  
  6.     if (!registry) return;  
  7.        
  8.     factory = gst_element_factory_find (name);  
  9.     if (!factory) return;  
  10.        
  11.     if (enable) {  
  12.         gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), GST_RANK_PRIMARY + 1);  
  13.     }  
  14.     else {  
  15.         gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), GST_RANK_NONE);  
  16.     }  
  17.        
  18.     gst_registry_add_feature (registry, GST_PLUGIN_FEATURE (factory));  
  19.     return;  
  20. }  
      傳給方法的第一個參數是要修改的element的名字,比如:vaapidecode或者fluvadec。

      這里主要的方法是gst_plugin_feature_set_rank(),它會設置element的rank。為了方便起見,rank分成NONE,MARGINAL,SECONDARY和PRIMARY,但任何數字都可以的。比如我們可用給某個element設置PRIMARY+1,那么它就比其他設置成PRIMARY的rank高,設置一個element的rank是NONE,會讓自動連接機制屏蔽它(永遠選不上)。


硬件加速視頻解碼和GStreamer的SDK

      GStreamer的SDK在2012年七月前是沒有硬件加速的視頻解碼的插件的。主要原因是有些還沒有完全寫完,還有一些問題。但請記住這個情況會在不久改變。

      有些插件可用在它們公開源碼的基礎上自己編譯出來,使用Cerbero編譯系統。有些插件是供應商已經編譯好了。

      下面會簡單介紹一下當前這些插件的情況。

vdpad在gst-plugin-bad

      針對VDPAU的GStreamer element,在gst-plugin-bad里面

      支持mpeg2,mpeg4和H264的編解碼

gstreamer-vaapi

      針對VAAPI的GStreamer element,項目的網址請猛戳這里

      支持mpeg2,mpeg4,H264,VC1和WMV3的編解碼

      可用直接和Clutter配合使用,這樣幀就可以一直在GPU里面

      和playbin2兼容

gst-omx      

      針對OpenMax的GStreamer element,項目網址請猛戳這里

      在不同的硬件下支持不同的編解碼

fluvadec

      針對VAAPI,VDPAU,DXVA2,XVBA和VDA的GStreamer element.

      根據不同的API,支持不同的編解碼


MPEG2 MPEG4 H.264 VC1
VAAPI
VDPAU
XVBA

DXVA2


VDA


      可用直接和Clutter配合使用,這樣幀就可以一直在GPU里面

      和playbin2兼容



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM