好吧,所以我写了一个自定义的VMR9分配器/演示器,似乎工作正常。但是,当我尝试将分配器/ Presenter表面中的视频帧复制到我的应用程序表面时,视频似乎闪烁。音频播放很好,所以我很确定这不是机器陷入困境或任何问题。这是我在渲染循环中的代码。
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();
}
这种闪烁消失了。我担心这在某种程度上是糟糕的形式/ hackish并且可能导致比它解决的更多问题。有没有人在这方面有经验?有更好的解决方案吗?
谢谢!
答案 0 :(得分:3)
如果你打算每帧都重新绘制整个视口,那么没有理由做清楚,它实际上可以产生很多性能提升,所以去吧!至于你的闪烁,那可能会有所不同。你在做你正在绘制WM_PAINT消息吗?如果是这样,您可能还想拦截WM_ERASEBKGND消息,并在获得它时简单地返回1。这可以防止窗口试图擦除背景,并帮助我摆脱过去的一些闪烁。
仅供参考:在Doom或Quake中做过noclip作弊,当你走到墙外时,一切都开始留下“小道”了吗?那是因为他们没有清除后台缓冲区,因为在正常情况下,每次都会重绘整个场景。我说如果它足够好对我来说它对我来说足够好了! :)
编辑:哦,还有更多的事情!我不确定它是否是必需的,但我总是在调用BeginScene()之后清楚。也可能导致你的闪烁。
答案 1 :(得分:0)
TBH我认为你最好编写自己的directshow渲染过滤器,将数据直接复制到纹理,然后用纹理在屏幕上绘制四边形。你会得到更好的表现。编写渲染过滤器实际上非常简单。特别是当您欣赏时,不必将其暴露给操作系统,因此大多数困难的DirectShow障碍都不需要跳过。
编辑:查看“转储过滤器”,它是微软DirectShow帮助程序代码的一部分......
答案 2 :(得分:0)
我遇到了同样的问题。在我的例子中,闪烁的原因是在BeginScene / EndScene对内的StretchRect调用中。