6,render的一些概念和可用庫

一,概念解釋android

什麼是渲染?這是高大上的說法,翻譯成正常語言,就是把圖像緩衝區的數據顯示到屏幕的過程,就是渲染。程序員

 

原理說白了很簡單,但實際操做中有太多因素須要考量。算法

OS/硬件提供的加速機制/解碼後圖像數據格式/字幕數據的格式。。。。編程

剛開始查找資料時,我老是試圖找到全部的渲染方式,後來發現這實在錯的比較離譜。由於說到底,這是一個圖形學的問題:如何在計算機屏幕上繪圖。不一樣的圖形庫有不一樣的繪圖接口,太多的廠商有本身的圖形庫,根本不可能窮舉出全部的圖形庫。咱們只能討論一些相對主流的方式。另外去找全部的圖形渲染方式也是沒有意義的,由於他們的理念大致上又是差很少的,只是API不一樣。惟一的要求是,你要畫的足夠快,由於若是你想一張張圖像看起來是連續的,那麼速度要達到24幀以上。固然,對於一些特殊應用,好比視頻會議,15幀的速度不會讓人有卡頓感,這個幀數也徹底Ok。windows

二,問題的概念空間與一些解決方案api

說完了,回到開始的問題,如何渲染。ide

這裏又有兩個問題須要解釋:性能

1.圖像緩衝區裏面的數據是什麼樣的?RGB仍是YUV,又是哪一種RGB,哪一種YUV?google

2.如何把緩衝區的數據搬到屏幕?CPU,普通的2D加速,仍是GPU,用GPU時,是OpenGL仍是D3D?spa

 

第一個問題:

這裏咱們只說幾個常見的。這裏的圖像緩衝區,特指解碼後的數據,而非對應屏幕顯示的那塊。由於對於目前的真彩色顯示器來講,屏幕對應的數據只有一種,就是RGB888。不管你給到的數據如何,傳輸到屏幕點亮色點的數據都會被驅動/硬件/總線給處理成這種格式。這是由屏幕的物理屬性決定的,物理屏幕就是TTL電路點亮的一堆小燈

常見的有RGB888/RGB565/YV12/I420p。

ps:實際解碼器出來的都是YUV數據,若是獲得RGB數據,一般也都是解碼器後面加了一步YUV2RGB的轉換,不過一般咱們也會把這塊功能算成是解碼器的。不過不絕對,須要看lib的做者如何看待這個問題。

第二個問題:

1.純粹的CPU(如今貌似不多有這種了),就是一個一個的往屏幕上畫點了,一個pixel一個pixel的畫,不太常見,也比較慢,由於操做內存太過頻繁。有些庫封裝了overlay/bitblt等操做,雖然看起來像CPU在作,實際上已經調用了2D加速了。

2.用2D加速的

Overlay

之前看資料,老看到Overlay什麼的東東,找了好久,彷佛也沒有誰專門給出一個標準定義,說什麼才叫Overlay。說下個人理解,Overlay一般是一個硬件意義上的名詞,由於屏幕上的東西,一般有不少層次,Overlay能夠作的就是直接把這層放到全部圖層上面。一般的用法是YUV數據直接給屏幕,Overlay硬件會替你作YUV2RGB轉換。這個詞貌似來自ms的directshow,有什麼主表面,離屏表面,overlay之分,實際上就是硬件圖層的意思。貌似有些硬件能夠支持RGB Overlay,不多見。有些圖形硬件能夠支持多個Overlay圖層,也就是說,你可使用Overlay同時在屏幕上顯示幾個不一樣的視頻。視頻監控的宮格多半就是這樣來的。

嵌入式裏面,Overlay還有一種常見作法,好比:一些有很高優先級的提示,要給用戶,這時就得把普通的提示框作成YUV的,而後提示顯示出來,能夠直接蓋到全部的圖層上去。

關於模擬Overlay,呵呵,凌亂了吧,實際上就是接口叫xxxOverlay,其實是把YUV轉成RGB,而後畫點的方式顯示,SDL中有這種接口。

最多見的Overlay類型是YV12,一是數據量小,二視頻壓縮的標準有關,由於Mpeg2/h264等標準,都強制要求這種格式,固然這兩點是相符相成的。

優勢就是快,缺點也比較明顯,若是要作視頻圖像後處理,好比放大縮小,人臉識別等操做,會比較麻煩。

Bitblt

比較常見的2d加速方式,把內存數據的數據直接傳輸到屏幕,或者搬到另外一塊內存中(內存拷貝)。

blit是個有淵源的詞語,這個詞的本意就是塊(block)移動(transfer)的縮寫blt,由於這個縮寫缺乏元音很差讀,因此後來加上了i,就變成blit。

實際上我搞不清這和DMA有什麼區別,但願有人指點一下區別。難道區別僅僅是BitBlt能夠同時縮放/旋轉,而DMA不能?

另外與Android提出的CopyBit有區別麼?我看沒啥區別啊。

優勢是在內存拷貝時,能夠同時作縮放/旋轉,缺點是隻能用RGB格式。

(2014.03.30更新:

1.查了一些資料,看了一下bitblt實現原理,除去縮放/旋轉的算法以外,涉及到內存搬移的應該是調用memcpy實現的,從這個角度來看,是用到了dma功能的,看來是沒有什麼區別的。只是memcpy的實現一般是考驗硬件性能和程序員水平的地方。

2.從copybit規定的interface來看,實際就是bitblt,估計只是bitlt這個單詞是ms提出的,google以爲不爽,起個新名子而已。

實際android到了4.0以後,已經取消掉了copybit HAL module,2d加速所有采用了GPU操做。在android 2.3代碼裏還殘存着一些痕跡。)

3.GPU

其實OpenGL和D3D就是GPU在軟件接口層面上的抽象。用opengl和d3d顯示視頻一般都是用texture方式來實現的,把一幀一幀圖像生成紋理數據,而後貼到vertex上去。

簡單解釋一下就是,先創建頂點座標,再創建紋理座標,再把頂點座標與紋理座標一一映射,完成貼圖。具體的要看一下OpenGL編程書籍了,這實在是一個複雜的題目。

先把屏幕四個點當成兩個三角形(由於3d api用三角形來表示平面,固然多邊形也支持,但遇到不支持的狀況,用兩個三角形就能夠組成一個矩形),把數據的一個點一個點對應到這個矩形上,就顯示了一幀。由於GPU一般是並行操做,像素生成率一般也足夠高。

這塊瞭解不夠多。很少說了。

三,常見的庫

這個一般又與OS有關係了,討厭死了。

先說Windows,又分幾個層次。先從底層提及。

純api就是

Windows GDI,windows平臺對圖形硬件的抽象,不少年了,比較成熟,效率應該比較OK。

DirectDraw,這個封裝的就是Overlay的操做接口,可是微軟已經中止支持了,不建議使用。

D3D,微軟的3D API,門檻比較高一些。

Direct2D,層級和GDI貌似差很少,Win7時代出現新玩意,看過一些資料,說這套API是取代GDI的,不過貌似微軟已經尾大不調了。

上述幾個API,VLC播放器裏面都有一些具體的實現,能夠看一下下。

另外就是DirectShow中的filter級別的。

VMR7,底層用DirectDraw封裝的,資料說只有XP好用,更老更新的平臺都不支持。

VMR9,底層用D3D實現,還在支持。

EVR,vista時代出現的東西,好像也是D3D作的(微軟你到底要鬧哪樣。。。。這麼多選擇)

其實dshow還有什麼overlay mixer,video render之類的filter,我以爲都沒有跑出我上面說的範圍。

說Linux吧。

X-window的api算一種,雖然一直用X,但對X的超多bug也很不滿,歷來沒看過。。。(吐血)

DirectFB,一般在嵌入式平臺纔會使用,桌面平臺上極少見到,抽象了幾乎全部的2D加速機制,接口操做和DirectDraw幾乎如出一轍。

直接用FrameBuffer提供的接口,嵌入式多見,不過一般這些接口裏面已經封裝了Overlay/BitBlt接口,不要只見樹木不見森林就好。

跨平臺的

SDL,算是比較經常使用的,API的使用還比較簡單,可是看代碼真心以爲太亂了,不過人家是跨平臺的,代碼亂真心是難以免。

 

最後有個比較慘痛的事實,由於你在寫播放器時,這些API可能都沒用,由於。。。。。你的圖形庫會再給你提供一套。。。。好吧,懂得原理,不少事情會簡單一些。

相關文章
相關標籤/搜索