2011-12-25 91 views
0

我有一个使用DSPACK组件库在Delphi 6中编写的DirectShow过滤器。它是一个推送源视频过滤器,它从我也写过的外部协作过程中接收其源帧。从DirectShow过滤器FillBuffer()调用中调用PeekMessage/GetMessage是否安全?

当调用我的Filters'FillBuffer()调用的工作线程被创建并运行时,当图形启动时,我从该工作线程执行的第一件事就是使用AllocateHWND()来处理WM_COPYDATA消息包含外部生成的帧。在线程被销毁之前,我摧毁了隐藏的窗口。换句话说,隐藏窗口是在调用FillBuffer()的工作线程的执行上下文中创建和销毁的。我的意图是让FillBuffer()在等待WM_COPYDATA或WM_QUIT消息时阻塞。外部协作过程将使用WM_COPYDATA消息和隐藏窗口的WndProcc()的句柄将帧提交给我的过滤器。我会在重写该引脚的Inactive()方法(感谢提示@RomanR)中发布WM_QUIT消息,以在过滤器关闭之前解除对FillBuffer()的调用。

我的问题是,从这个场景的FillBuffer()调用中调用PeekMessage()或GetMessage()是否安全?或者在执行DirectShow图形的情况下可能出现这种潜在的缺陷吗?另外,您是否看到我需要考虑的总体方法中的缺陷?

回答

1

安全,但不太合理。在后台工作线程上调用FillBuffer,后者通常没有窗口。这可能只是你要实现消息循环的窗口。此窗口仅用于接收WM_COPYDATA消息。这听起来像是可以解决的,但是如果没有帮助窗口,通过在应用程序之间通过命名文件映射和事件传递数据,您可能会更容易。在视频(你有音频,对吗?)的情况下,你也可以体会到更小的性能开销。

+0

没有音频,只有来自外部进程处理的RTP会话的视频。另外,隐藏窗口只是默认窗口过程的借口,没有其他窗口消息处理正在进行(但是我按照您对未处理消息的指示调用DefWindowProc())。我尝试使用由系统页面文件支持的共享内存文件,但是我发现写入之间的共享内存区域失效触发的一堆软页面错误确实令人不安(每秒25次)。为什么SendMessage()调用比共享内存方法慢得多? – 2011-12-25 22:50:07

+1

通过文件映射,您可以在一侧引发事件,您可以在另一侧看到它并接管已存在的数据。在这里,你肯定有相同的+额外的数据重复(至少一次,然后取决于操作系统的实现)+窗口,消息循环+整个处理在发送方处理时被阻塞,而您在接收方处理消息。使用这些少量数据的音频并不是什么大事,但对于视频来说,它变得越来越重要。 – 2011-12-26 06:05:07

+0

是否有共享内存变量在操作期间不会产生软页面错误?我真的想避免这些。链接到进一步的信息或示例代码,如果有,你有它。谢谢。 – 2011-12-26 14:42:34

相关问题