目標css
視頻的硬件解碼近來發展很是快速,尤爲是在低功耗的設備上。本教程會講述一些硬件加速的背景知識並解釋一下GStreamer是怎麼作的。html
悄悄告訴你,若是設置正確地話,咱們什麼也不用作,GStreamer自動作完這一切的。linux
介紹git
視頻解碼是很是消耗CPU的一個任務,尤爲是1080P這種高分辨率的高清節目。幸運的是,如今的顯卡都帶了可編程的GPU,若是咱們用GPU用來作視頻解碼,那麼CPU就能夠解放出來作其餘的任務了。低功耗的CPU是沒法作解碼這樣的工做的,這時硬件的配合就是必須的了。編程
目前來講(2012.07),每一個GPU的製造商都提供了訪問它們的硬件的方法(API),不幸的是各家並不相同,並無一個強制的標準。api
VAAPI(Video Acceleration API):2007年Intel設計的,目的是在Unix操做系統的XWindow系統下運行,如今開源了。如今不只僅侷限於Intel的GPU了,其餘製造商也可使用了。GStreamer經過gstreamer-vaapi和fluvadec這個插件來使用。xcode
VDPAU(Video Decode and Presentation API for Unix):2008年NVidia設計的,最先也是運行在Unix的XWindow系統下,如今一樣開源了。雖然一樣已是開源庫了,但除了NVidia本身外尚未其餘製造商使用。GStreamer經過vdpau和fluvadec這個插件來使用。app
DXVA(DirectX Video Acceleration):微軟爲了Windows系統和XBox360定製的。GStreamer經過fluvadec這個插件來使用。ide
XVBA(X-Video Bitstream Acceleration):AMD設計,在Linux操做系統的XWindow系統下下X Video的擴展。目前在AMD的ATI顯卡中有支持。GStreamer經過fluvadec這個插件來使用。spa
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屬性的值。代碼以下:
這裏主要的方法是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兼容