2009-09-20 113 views
2

好吧,所以我寫了一個自定義的VMR9 Allocator/Presenter,似乎工作正常。但是,當我嘗試將視頻幀從分配器/演示者表面複製到我的應用程序表面時,視頻看起來閃爍。音頻播放是好的,所以我相當肯定這不是一個機器陷入困境或任何問題。這是我在渲染循環中的代碼。DirectX閃爍視頻

g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0); 

// render the scene 
if (SUCCEEDED(g_pd3dDevice->BeginScene())) 
{ 
//g_pd3dDevice->SetRenderTarget(0, g_pd3dSurface); 

g_pd3dDevice->StretchRect(vmr9_ap->renderSurface, src, g_pd3dSurface, dest, D3DTEXF_NONE); 

    // end the scene 
    g_pd3dDevice->EndScene(); 
} 

但是,如果我將其更改爲這個(註釋掉清除緩存)

// g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0); 

// render the scene 
if (SUCCEEDED(g_pd3dDevice->BeginScene())) 
{ 
//g_pd3dDevice->SetRenderTarget(0, g_pd3dSurface); 

g_pd3dDevice->StretchRect(vmr9_ap->renderSurface, src, g_pd3dSurface, dest, D3DTEXF_NONE); 

    // end the scene 
    g_pd3dDevice->EndScene(); 
} 

這個閃爍消失。我擔心這種方式很糟糕,可能會導致比解決問題更多的問題。有沒有人有這方面的經驗?有更好的解決方案嗎?

謝謝!

回答

3

如果您打算每畫面重新繪製整個視口,沒有理由做清晰的事情,並且實際上可以產生很多性能提升,所以就去做吧!至於你的閃爍,這可能是不同的。你在做你正在繪製WM_PAINT消息嗎?如果是這樣,您可能還想攔截WM_ERASEBKGND消息,並在獲取時立即返回1。這可以防止窗口試圖擦除背景,並幫助我擺脫過去的一些閃爍。

僅供參考:曾經在Doom或Quake做過noclip作弊,當你走出圍牆時,所有的東西都開始留下「痕跡」了嗎?這是因爲他們沒有清除後臺緩衝區,因爲在正常情況下,整個場景都會重新繪製。我說如果ID足夠好,對我來說就夠了! :)

編輯:哦,還有更多的事情!我不確定是否需要它,但我總是在調用BeginScene()後清除AFTER。也可能導致你的閃爍。

+0

謝謝!這很有道理。如果我有聲望,我會投票贊成。 – Alex 2009-09-20 06:17:12

+0

哦,並且繪圖是在D3Dmage中響應WPF中的CompositionTarget.Rendering事件完成的。 – Alex 2009-09-20 06:20:36

+0

重新編輯:在BeginScene周圍的每張DX卡上都不會做任何事......它不是,甚至不需要,嚴格來說是需要的 – Goz 2009-09-20 08:46:10

0

TBH我認爲你最好編寫自己的directshow渲染過濾器,將數據直接複製到紋理,然後用紋理在屏幕上繪製四邊形。你會得到更好的表現。編寫渲染過濾器其實很簡單。特別是當你感謝你不必將它暴露給操作系統,所以大多數困難的DirectShow障礙不需要跳過。

編輯:查找「轉儲過濾器」,此番微軟的DirectShow助手代碼的一部分...

+0

你能提供一個鏈接嗎? – Alex 2009-09-20 18:37:50

+0

不是一個鏈接,但所有你需要的信息已經在SDK中。 – Goz 2009-09-21 08:20:58

0

我面臨着同樣的問題。在我的情況下,閃爍的原因是在一個BeginScene/EndScene對內的StretchRect調用。