簡體   English   中英

最快的方式解碼和同時顯示許多H264視頻C#

[英]Fastest way to Decode and Display many H264 Videos Simultaneously C#

正如您可能從問題標題中推測的那樣,我們需要同時解碼和顯示多個(例如,8個)H.264編碼視頻(並保持它們所有時間同步,但這是另一個問題的另一個問題)。 視頻通常為25 FPS,分辨率為640x480。

在我解決問題的關鍵之前,我將提供一些背景知識。

該功能需要融入相當大的C#3.5(WinForms)應用程序。 視頻將占用應用程序中的矩形 - 托管代碼需要能夠指定每個視頻的繪制位置以及大小。

我們在C#中獲取H264數據包並將其激發到本機H264解碼器以獲取YUV12圖像數據。

早期的嘗試包括將YUV12圖像轉換為RGB24,將BitBlt將它們轉換為從C#傳遞到本機代碼的HWND。 功能上,所有BitBlt都必須在UI線程上發生,這導致它在顯示多個視頻時陷入困境(在2.6 GHZ核心2 duo上)。

當前嘗試在啟動時旋轉每個cpu-core的一個線程並負載平衡跨這些線程的視頻解碼/顯示。 這種表現是令人興奮的(我發現觀看任務管理器比顯示的視頻更有趣)。 UI方面,它留下了很多不足之處。

我們從非UI線程開始繪制在UI線程(例如,停靠在WinForms控件中的面板)上創建的HWND毫秒,由於WinForms的非線程安全性,我們開始獲得各種各樣的時髦行為。 這導致我們用本機代碼創建HWND並繪制到那些,用C#提供它們應該在屏幕坐標中繪制的矩形。

爾加! CanOfWorms.Open()。

問題:當C#應用程序獲得焦點時,它會跳轉到Z-Order的前面並隱藏視頻窗口。 解決方案:將視頻窗口始終放在頂部。

問題:當用戶切換到另一個應用程序時,視頻窗口仍然位於頂部。 解決方案:檢測C#應用程序的激活和停用,並相應地顯示/隱藏視頻窗口。

問題:用戶說:“我希望我在另一台顯示器上編輯Word文檔時在一台顯示器上播放視頻!” 解決方案:告訴用戶關閉並且Word無論如何都很糟糕。

問題:我被解雇了。

等等

我想問題的關鍵在於我們在非UI線程上創建了HWND,並且我們想要“模擬”嵌入在C#應用程序中的那些。

有什么想法/建議? 我完全在這里吃午飯嗎?

如果存在一個完全不同的方法,我就會采取完全不同的方法(這個項目需要大量的學習 - 贏得彩票的可能性比我在路上的每一步選擇最佳方法的可能性更大)。

忘記BitBlt-ing並執行此操作:

  • 對於您希望播放視頻的每個窗口,創建一個DirectShow圖形並將圖形的渲染器附加到該窗口
  • 在圖表中的渲染器之前放入samplegrabber過濾器。 它將允許您進行回調,您可以在其中填充緩沖區
  • 而不是blitting,解碼到samplegrabber中提供的緩沖區。

另外,我猜你可以將原始YUV12放入緩沖區,因為VMRenderer能夠直接顯示它們。

使用DirectShowNet庫。

編輯:

是的,順便說一下,如果視頻在同一個“畫布”上,你可以使用與渲染器相同的技術並只創建一個大窗口,然后“手動”移動解碼的視頻矩形並將它們放入幀緩沖區緩沖區。

再編輯:

BitBlts總是被序列化,即它們不能並行運行。

我們從非UI線程開始繪制在UI線程(例如,停靠在WinForms控件中的面板)上創建的HWND毫秒,由於WinForms的非線程安全性,我們開始獲得各種各樣的時髦行為。 這導致我們用本機代碼創建HWND並繪制到那些,用C#提供它們應該在屏幕坐標中繪制的矩形。

什么樣的時髦行為? 如果你的意思是閃爍或繪制延遲,你是否試圖鎖定()面板或任何其他類進行線程/繪圖同步? 再次:當您將數據發送到解碼器,接收圖像,轉換它然后使用OnPaint處理程序繪制它時,確切的問題是什么。 (設置一個以25fps循環的不同線程,調用panel1.Invalidate()然后)

我想問題的關鍵在於我們在非UI線程上創建了HWND,並且我們想要“模擬”嵌入在C#應用程序中的那些。

不要那樣做。 嘗試在c#應用程序中繪制接收的數據。 一般來說,我不會建議混合本機代碼和c#。 在本機代碼中使用h264解碼器是唯一的例外。

使用你的線程解碼視頻數據包(正如你已經做的那樣),然后讓一個線程循環並調用Invalidate(如上所述)。 然后為要顯示視頻的每個面板都有一個OnPaint處理程序。在此處理程序中獲取最新的視頻圖片並繪制它(e.Graphics)。

我希望這有所幫助,但也需要有關該問題的更多信息......

我喜歡之前發布的DirectShow答案,但我希望根據您的問題摘錄中包含一個可能更容易實現的附加選項:

功能上,所有BitBlt都必須在UI線程上發生,導致它在顯示多個視頻時陷入困境

我的想法是從該代碼開始,並使用當前可用的 Visual Studio 2010的Async CTP並包含上線許可證。 從那里開始修改現有代碼應該是一個相對簡單的響應:只需在幾個地方添加await和async關鍵字,其余的代碼應該基本保持不變。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM