2

好吧,所以我写了一个自定义的 VMR9 分配器/演示器,它似乎工作正常。但是,当我尝试将视频帧从分配器/演示器表面复制到我的应用程序表面时,视频似乎闪烁。音频播放很好,所以我相当确定这不是机器陷入困境或其他任何问题。这是我在渲染循环中的代码。

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,可能会导致比它解决的问题更多的问题。有没有人有这方面的经验?有更好的解决方案吗?

谢谢!

4

3 回答 3

3

如果您打算每帧重新绘制整个视口,则没有理由进行清除,它实际上可以产生很多性能提升,所以去吧!至于你的闪烁,那可能是不同的东西。你在画 WM_PAINT 消息吗?如果是这样,您可能还想拦截 WM_ERASEBKGND 消息,并在收到它时简单地返回 1。这可以防止 Windows 试图擦除背景,并帮助我摆脱了过去的一些闪烁。

仅供参考:有没有在 Doom 或 Quake 中使用 noclip 作弊,当你走到墙外时,一切都开始留下“痕迹”?那是因为他们没有清除后台缓冲区,因为在正常情况下,无论如何每次都会重绘整个场景。我说如果它对 id 来说足够好,那对我来说就足够了!:)

编辑:哦,还有更多!我不确定它是否需要,但我总是在调用 BeginScene() 之后做清楚的事情。也可能导致您的闪烁。

于 2009-09-20T04:39:08.267 回答
0

TBH 我认为你最好编写自己的directshow 渲染过滤器,将数据直接复制到纹理,然后在屏幕上用纹理绘制一个四边形。你会得到更好的表现。编写渲染过滤器实际上非常简单。尤其是当您意识到不必将其暴露给操作系统时,无需跳过大多数困难的 DirectShow 障碍。

编辑:查找它作为 Microsoft 的 DirectShow 帮助程序代码的一部分提供的“转储过滤器”......

于 2009-09-20T08:19:53.217 回答
0

我面临着同样的问题。就我而言,闪烁的原因是在 BeginScene/EndScene 对内的 StretchRect 调用中。

于 2015-09-23T13:36:30.660 回答