現在,使用視訊會議系統遠端協同辦公、溝通交流,已經非常普遍了。如果我們要開發自己的視訊會議系統,那麼,GPU解碼渲染技術是不可缺少的。
在視訊會議系統中,經常需要同時觀看會議中多個參會人員的影片影像,另外,還可能需要同時觀看某人分享的螢幕。
隨著大家對會議中影片影像的要求越來越高,所以在適配會議中,起步解析度就是1280*720。而1920*1080已經是標配,2K解析度也不算太高。
但是,對程式而言,高解析度的影片影像的編碼、解碼、渲染都是消耗效能的大戶。
一.為什麼必須使用GPU解碼渲染影片?
在視訊會議中,同時看多路高畫質影片影像是基礎的硬指標。每一路影片影像都是需要解碼和渲染的,如果解碼和渲染的工作都交給CPU來做(即所謂的“軟解” CPU-based Software Decoding),那麼CPU的負載就會立馬飆升,嚴重時會CPU跑滿而導致系統卡死。
何況,CPU並不擅長做影像處理的工作。對於H264/H265影片,解碼和渲染都是GPU專業技能,所以,在視訊會議中,我們要儘可能地使用GPU也就是顯示卡來解碼渲染影片(即所謂的“硬解”,也稱“硬體加速” GPU-accelerated Hardware Decoding)。
二. 顯示卡與GPU解碼、渲染
顯示卡,一般肯定都是支援GPU渲染的,然而,並不是所有的顯示卡都支援GPU解碼影片。對於指定的顯示卡,我們檢視其效能引數,就可以知道其是否支援H264/H265影片解碼,且能支援解碼的影片最高解析度是多少。
目前市面上主流的顯示卡主要有三種:Intel的集顯(也叫核顯)、NVIDIA的N卡、以及AMD的A卡。
在程式中想要使用GPU來解碼渲染影片,首先要看這臺電腦配備的顯示卡是哪種,然後再使用該顯示卡對應的程式介面去訪問它。
下面是每種顯示卡所使用的程式訪問介面/技術。
我們可以先這樣簡單地理解顯示卡,即 顯示卡 = GPU + 視訊記憶體。而GPU是操作不了記憶體的,記憶體是由CPU操作的,GPU只能對視訊記憶體進行操作。
GPU要解碼H264/H265影片影像,先要將其複製到視訊記憶體中,再由GPU解碼,解碼後得到的影像資料(一般是YUV格式)也是位於視訊記憶體中,此時,直接將該資料提交給GPU去渲染,效能就非常高效了。
之前,我們嘗試過一種方案:解碼由GPU來做,然後渲染由CPU做。即我們把GPU解碼得到的YUV資料複製回記憶體,再交由CPU去渲染,但是這樣效率就大打折扣了。
因為當影片影像的解析度很高時,解碼得到的YUV資料就非常大,這時將其從視訊記憶體複製回記憶體,就需要消耗大量的CPU。
經過我們測試,這樣的方案很雞肋,還不如直接使用CPU解碼渲染來得方便省事。
當然,最佳方案是解碼和渲染全部交由GPU來執行。如果有些顯示卡不支援GPU解碼,那麼,就只能由CPU解碼,GPU來渲染了。
三.對比測試
我們使用 OMCS入門Demo 來做測試(OMCS 支援使用集顯、N卡、A卡解碼渲染影片),分別在開啟和關閉GPU解碼渲染功能時,看看CPU和GPU的佔用情況。
首先將攝像頭解析度設定成1920*1080,幀頻設為30fps,如下程式碼所示:
multimediaManager.CameraVideoSize = new Size(1920, 1080); multimediaManager.MaxCameraFrameRate = 30;
然後,我們可以透過設定 GpuEnabled4Decode 屬性來控制是否開啟GPU解碼渲染:
multimediaManager.Advanced.GpuEnabled4Decode = true; //是否開啟GPU解碼渲染
OMCS入門Demo按照上面修改後,重新編譯客戶端。接下來就可以開始我們的測試工作了。
先在我同事的電腦上啟動Demo客戶端,登入aa01賬號。然後,在我的電腦上啟動客戶端後,登入aa02賬號,然後,aa02去連線aa01的攝像頭,這樣,aa02就可以看到aa01的影片影像了。
此時,我電腦上的demo客戶端aa02在收到了來自aa01影片影像幀(H264)後,會將其解碼,然後再在UI上渲染出來。
1. 使用CPU解碼渲染影片
我們先關閉GPU解碼渲染功能:
multimediaManager.Advanced.GpuEnabled4Decode = false; //關閉GPU解碼渲染
測試時看看CPU的佔用情況:
可以看到,Demo客戶端程序CPU佔用率為8%,而GPU的佔用為0,表示沒有使用GPU。
我這臺電腦的CPU型號是 AMD Ryzen 7 4700G with Radeon Graphics,算是很不錯的,如果是次一點的CPU,解碼渲染一路1080p的影片,CPU能跑到20%了。
2. 使用GPU解碼渲染影片
接下來,我們開啟GPU解碼渲染功能:
multimediaManager.Advanced.GpuEnabled4Decode = true; //開啟GPU解碼渲染
在看看CPU的佔用情況:
對比非常明顯,現在CPU的利用率降到了0,而GPU利用率接近7%。
這樣看來,測試的這臺電腦的顯示卡,可以同時解碼渲染13~14路1920*1080的全高畫質影片,如果是1280*720的高畫質影片,應該可以同時解碼渲染20多路了,這樣,對於一般的視訊會議系統來說,是綽綽有餘了。
透過上面的介紹,你應該已經明白了,為什麼視訊會議系統中必須使用GPU來解碼渲染影片了吧。