DirectX 视频闪烁
好吧,所以我写了一个自定义的 VMR9 Allocator/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();
}
这种闪烁就会消失。我担心这在某种程度上是一种不好的形式/黑客行为,并且可能会导致比它解决的问题更多的问题。有人有这方面的经验吗?有更好的解决方案吗?
谢谢!
Alright, so I wrote a custom VMR9 Allocator/Presenter which seems to work fine. However, when I attempt to copy video frames from the Allocator/Presenter surfaces into my application surfaces, the video appears to flicker. Audio playback is fine so I'm fairly certain it's not an issue of the machine being bogged down or anything. This is the code I have in my render loop.
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();
}
However, if I change it to this (commenting out clearing the buffer)
// 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();
}
this flickering goes away. I'm worried that this is somehow bad form/hackish and might cause more problems than it solves. Does anyone have any experience in this area? Is there a better solution?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您打算每帧重新绘制整个视口,则没有理由进行清除,而且它实际上可以带来很多性能提升,所以就去做吧!至于你的闪烁,那可能是不同的。您正在使用 WM_PAINT 消息进行绘图吗?如果是这样,您可能还想拦截 WM_ERASEBKGND 消息,并在收到它时简单地返回 1。这可以防止 Windows 尝试擦除背景,并帮助我消除了过去的一些闪烁。
仅供参考:在《毁灭战士》或《雷神之锤》中,noclip 曾经作弊过吗?当你走到墙外时,一切都开始留下“痕迹”?这是因为他们没有清除后台缓冲区,因为在正常情况下,整个场景每次都会重新绘制。我说如果它对 id 来说足够好,那么对我来说就足够了! :)
编辑:哦,还有更多事情!我不确定是否需要,但我总是在调用 BeginScene() 之后进行清除。也可能导致你的闪烁。
If you intend to repaint the entire viewport every frame there is no reason to do a clear, and it can actually yield a lot of performance gains, so go for it! As for your flickering, that might be something different. Are you doing you're drawing in a WM_PAINT message? If so, you may want to also intercept the WM_ERASEBKGND message and simply return 1 when you get it. This prevents windows from trying to erase the background and has helped me get rid of some flickering in the past.
FYI: Ever do the noclip cheat in Doom or Quake, and when you walk outside a wall everything starts leaving "trails" all over? That's because they're not clearing the back buffer, since under normal circumstances the entire scene would be redrawn every time anyway. I say if it's good enough for id it's good enough for me! :)
Edit: Oh, and on more thing! I'm not sure if it's required or not, but I always do my clear AFTER calling BeginScene(). Could also be contributing to your flicker.
TBH 我认为你最好编写自己的 directshow 渲染过滤器,将数据直接复制到纹理,然后使用纹理在屏幕上绘制一个四边形。你会得到更好的表现。编写渲染过滤器实际上非常简单。特别是当您意识到不必将其暴露给操作系统时,因此不需要跨越大多数困难的 DirectShow 障碍。
编辑:查找“转储过滤器”,它是 Microsoft DirectShow 帮助程序代码的一部分......
TBH i reckon you are best off writing your own directshow render filter that copies the data directly to a texture and then drawing a quad over the screen with the texture. You'd get much better performance. Writing a render filter is actually pretty easy. Especially when you appreciate you don't have to expose it to the operating system so most of the difficult DirectShow hurdles don't need t be jumped.
Edit: Look up the "Dump Filter" it comes as part of Microsoft's DirectShow helper code ...
我面临着同样的问题。就我而言,闪烁的原因是在 BeginScene/EndScene 对内的 StretchRect 调用中。
I was faced with the same problem. In my case, the flickering reason was in StretchRect call inside of a BeginScene/EndScene pair.