用Qt5的Qpainter畫視頻解碼的圖像,發現CPU佔用極高(50%),有方法能夠降低cpu佔用嗎?
使用Qt5畫解碼的視頻圖像,通過槽函數運行update方法觸發paintevent重繪,CPU佔用率極高,有沒有方法降低CPU使用率,能否使用QOpenGL的硬體加速渲染來降低CPU佔用?
qt widgets用的是cpu渲染,而不是gpu,性能並不優秀,只適合用來做界面,而不是做多媒體。
做多媒體的話,qt有專門封裝的QtMultiMedia類庫。其中包含了音頻、視頻、攝像解碼、處理、播放。其中有專門用於播放的控制項。
總之,盡量不要手擼paintEvent
——————————
另,還可以借用第三方更專業的庫。比如ffmpeg+opencv。
qt+opencv聯合開發gui是很常見的,網上不難搜到教程最後,另一位答主推薦的方法是最好的,用QOpenGlWidget,這個類的繪製操作是通過opengl渲染,走的就是gpu,而不是常規QWidget那樣走cpu用QOpenGLWidget(不要用QGLWidget,高DPI有坑),在它的paintEvent中以smooth模式畫drawImage,定時update,最簡單高效
使用QPainter繪製視頻圖像不是一個好的解決方案:
1、YUV / RGB 轉換費CPU2、QPainter大面積繪製效率不高OpenGL是一個不錯的選擇,目前移動設備上很多都是用GLES實現視頻渲染。
大概思路是:創建一個texture實現一個shader用於YUV / RGB 轉換
每次渲染將視頻數據update到texture將texture繪到一個表面50% 還極高啊……我還見過 2000% 的呢。視頻的話,上專業工具試試?
正如依雲所說的一樣,佔用50%的cup不能肯定是演算法沒有優化。
圖形的東西就是耗費cup,所以很多qt的模擬器軟體都上幾百個cpu的。qt creator自己有profile,跑一下看看是不是繪製函數耗時。
qt自帶圖形繪製的效率本來就比較差,甚至在幾百個表格控制項刷新的情況下就開始卡了。
不過就我的經驗,僅僅貼圖上去不解碼,我覺得qt自帶引擎的性能還是應該夠的。當然得看你的解析度了,以及update的頻率了。
另外qt有opengl widget,嘗試直接用opengl代替你的繪製看看。
QPainter 不是用來渲染視頻的,是用來自繪 GUI 的,它在 Windows 中底層應該使用了 GDI,缺乏顯卡加速,性能達不到繪製視頻的要求。另外,視頻繪製也不應該使用事件驅動,使用事件驅動會讓繪製操作運行在主線程里,這有可能阻塞 UI 事件響應,顯然是不合理的。
使用 Qt 繪製視頻有兩個選擇,要麼使用 QGLWidget,要麼拿到 widget 的窗口句柄(好像是 winid() 這個函數的返回值)或者窗口位置,配合其他工具(opengl、directx等,在 linux 中我推薦試試 SDL,介面比較友好)自行繪製。RGB/YUV變換在手機端還有個問題就是費時例如1280*960的圖像做yuv-&>rgb變換,在普通android手機上約需30ms~100ms具體到使用opengl直接渲染yuv數據,大致步驟上面有答主已經答了,我來上一點具體代碼1. shader部分可以參考webrtc 的render實現部分,open_gles20.mm (鏈接需翻牆),在shader中做YUV -&> RGB565變換。(需要注意Y/U/V uniform的綁定)這部分代碼是基於GLES20的,可以直接搬到Qt中。2. Qt中QOpenGLWidget 支持GLES20,參考Qt中的example程序即可
請問樓主是如何顯示cpu佔用的呢
解碼後的數據,是否是通過memcpy放到緩存中,然後paintEvent再通過緩存中畫到屏幕上QPainter?
memcpy會耗很多CPU的。QT並沒有想VC那種雙緩衝機制,這樣數據必須在paintEvent中準備好,不需要拷貝數據等,才能節省CPU,很難辦到。
沒有人提到用gstreamer嗎?難道就我一個人這麼干?
用Qt做了界面,用Gst做的後端,看視頻,放電影,聽音樂,一樣都不少。Qt 5以後也有多媒體的支持了,沒用過。我還是用的4.8,所以只能自己找個後台啦推薦閱讀:
※如何用 C++ 在 GUI 中畫出各種平衡樹插入刪除的動態變化?
※Qt多線程編程中子線程如何調用主線程中的成員變數?
※MFC、Qt、WPF?該用哪個?