源代碼下載 算法
在PC機上,對於YUV格式的視頻如YV12,YUY2等的顯示方法,通常是採用DIRECTDRAW,使用顯卡的OVERLAY表面顯示。OVERLAY技術主要是爲了解決在PC上播放VCD而在顯卡上實現的一個基於硬件的技術。OVERLAY的出現,很好的解決了在PC上播放VCD所遇到的困難。早期PC處理能力有限,播放VCD時,不但要作視頻解碼工做,還須要作YUV到RGB的顏色空間轉換,軟件實現很是耗費資源,因而,YUV OVERLAY表面出現了,顏色空間轉換被轉移到顯卡上去實現,顯卡作這些工做是具備天生優點的。編程
隨着顯卡技術的發展,OVERLAY的侷限性也愈來愈充分的暴露出來。通常顯卡只支持一個OVERLAY表面,用OVERLAY實現多畫面比較困難,視頻和文本的疊加也有困難,固然,要實現一些特效就更難了。更重要的是,OVERLAY技術在顯卡上是屬於2D模塊,在高品質3D遊戲的推進下,如今的顯卡的功能和性能,主要體如今3D模塊上,廠商投入最大的,也是在GPU的3D模塊上。OVERLAY技術沒法利用和發揮顯卡GPU的3D性能。微軟早就中止了對DIRECTDRAW的支持,鼓勵開發人員轉向DIRECT3D,因此OVERLAY也沒法使用新的API。架構
早期的3D渲染,主要是使用CPU作的,顯卡作的較少。後來,顯卡GPU的處理能力愈來愈強,承擔的3D渲染功能也愈來愈多,開始使用的是固定渲染管線,也就是說全部的渲染算法都是顯卡內置的,咱們只能組合使用這些算法。如今的顯卡採用的都是可編程的渲染管線,也就是說咱們能夠編寫本身的渲染算法,下載到顯卡上去執行,替換固定渲染管線算法,靈活性大大提升。隨着GPU效能的提升,顯卡在圖像處理、視頻處理、科學計算等領域獲得了普遍的應用。性能
使用D3D渲染YUV視頻,能夠採用D3D SURFACE渲染,也能夠採用D3D紋理來渲染。SURFACE渲染比較簡單,但功能限制較多,下面咱們只討論D3D紋理視頻渲染。紋理視頻渲染,就是把視頻數據填充到二維紋理中,結合咱們本身寫的一段像素Shader代碼,送到顯卡的GPU渲染管線中去渲染。測試
如下假設讀者瞭解所討論的視頻格式細節。spa
對於YV12視頻數據,能夠建立三個紋理,分別填充Y、U、V視頻數據。對於缺失的U、V採樣點,咱們能夠利用顯卡內置的雙線性濾波算法插值出來,這是簡單的方法。固然,也能夠採用更好的圖像插值算法,以達到更高的圖像質量,這須要咱們經過Shader實現咱們的插值算法,而後分別把U、V渲染到紋理,實現更好的插值。相對與雙線性濾波,缺點是複雜更度高,效率低。U、V插值後,視頻數據從YUV420轉換爲YUV444,而後作顏色空間轉換,從YUV444轉換爲RGB32,轉換的Shader代碼很簡單,就是一個矩陣乘法運算。對於I420數據,就是把YV12數據的U、V數據在內存中的位置對調,其餘處理和YV12同樣。.net
NV12格式,Y平面和YV12同樣,UV部分是打包格式。因此UV部分須要單獨處理,先把UV部分填充到一個紋理中,而後對UV紋理作兩次簡單的渲染到紋理,從而把U、V數據分別渲染到兩個紋理。通過這樣的處理,咱們獲得的數據就和YV12的數據同樣了,接下來的處理就能夠參照YV12的處理流程和方法了。視頻
對於打包格式的數據YUY2,渲染時須要插值出缺失的U、V採樣。YUY2在只在奇數像素上缺失U、V採樣,這樣處理的時候須要區分奇偶像素,對於偶數像素,不須要作U、V插值,直接作顏色空間轉換。對於奇數像素,須要利用相鄰的U、V採樣作插值,能夠採用Catmull-Rom插值算法或者線性插值算法。插值後,就能夠作顏色空間轉換。UYVY的作法和YUY2相似。blog
對於RGB格式,我所使用的NVIDIA GeForce 9800 GT顯卡支持RGB32,RGB555,RGB565,不支持RGB24。因此對於RGB24,須要在Shader代碼中分別取出R、G、B,再組成RGB32輸出便可。RGB32,RGB555,RGB565不須要額外處理,能夠直接渲染。遊戲
對於平面文本疊加,採用了微軟提供的CD3DFont類,但這個類不支持中文,我在這個類的基礎上作了一些修改,實現了一個支持中文的文本疊加類。這兩個類互相配合,能夠高效地實現平面文本疊加。
以上所討論的內容,均使用Direct3D9.0c進行了驗證測試。對OpenGL瞭解很少,但我想這些方法對於OpenGL應該一樣適用,畢竟這兩個3D架構在PC上實現的功能是相近的。
使用3D渲染平面視頻,能夠實現多種特效,像多畫面、畫中畫、文本疊加、縮放,都很容易實現,性能也很好。若是結合其餘3D技術,還能夠作出很炫很酷的特效,就看咱們的想象力了。
from:http://blog.csdn.net/dengzikun/article/details/5824874