繁体   English   中英

DirectShow将sampleGrabber转换为ISampleGrabber

[英]DirectShow cast sampleGrabber to ISampleGrabber

我有一个奇怪的错误,我无法绕过头脑。 我有一个在运行的单独线程中创建的图表,我正在尝试访问在控制台应用程序中工作的线程之外的IBaseFilter sampleGrabber但是我将代码移动到一个新项目,并且我正在尝试将sampleGrabberISampleGrabber运行时抱怨空引用异常。 如果我调试sampleGrabber它确实有接口ISampleGrabber但是我不能再抛出它了。 在运行图形的线程中移动代码允许我进行转换,但它不适合我的应用程序。

如何通过将一个sampleGrabberISampleGrabber失败来显示null引用异常?

问题是DirectShow过滤器是早期的COM类,它们在引用计数,接口,标记,持久性的一部分中实现COM的子集 - 基本上所有好事都持续了多年 - 但是它们完全忽略了公寓。 DirectShow本身是多线程的,通常有一个控制线程,并且有工作流线程。 DirectShow概念假设您可以轻松地在线程之间传递接口指针,并且不会涉及,预期和需要编组。

然后.NET检查了COM包装器,而DirectShow.NET包装了接口指针,好像它们是功能齐全的公寓感知COM指针一样。 与此同时,Microsoft停止向DirectShow提供更新(例如,使用免费的线程编组器提供Sample Grabber),最终在.NET上遇到问题时,您无法通过接口指针执行一个简单的操作。

在本机代码域中使用API​​仍然没有问题,因为您可以跳过编组并使用直接指针。

您在一个公寓上构建图形,然后您从另一个公寓的Sample Grabber中回复(或者,在您的方案中,您只需在工作线程上执行某些操作)。 您不能使用原始接口指针,尤其是 那些在成员变量中,因为.NET运行时检查会遇到公寓不匹配,尤其是试图编组另一个公寓的接口指针。

如果它是带有源代码的自定义过滤器,您可以添加自定义IMarshal实现或利用免费的线程编组器来修复本机代码端的.NET问题,或者添加帮助程序以跨公寓传递指针。

在.NET代码域中,最好的方法是避免使用来自多个公寓的指针。 可能有选择,但我认为最简单的选择是

  • 在MTA中工作,可以让多个线程访问DirectShow接口指针
  • 使用CLSID_FilterGraphNoThread版本的Filter Graph Manager
  • 在专用线程上初始化和终止过滤器图形,在图形操作期间调度窗口消息

也就是说,要么使用STA,要么没有额外的线程接触指针,否则不使用STA。

在玩了IGlobalInterface并思考了Roman的评论后,我意识到设置处理samplegrabber的函数最好是在另一个线程中,从而绕过STA。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM