gpt4 book ai didi

c# - DirectShow 将 sampleGrabber 转换为 ISampleGrabber

转载 作者:行者123 更新时间:2023-11-30 12:10:44 27 4
gpt4 key购买 nike

我有一个奇怪的错误,我无法解决问题。我在一个运行的单独线程中创建了一个图形,我试图在控制台应用程序中工作的线程之外访问 IBaseFilter sampleGrabber 但我将代码移动到一个新项目并且我在哪里我试图将 sampleGrabber 转换为 ISampleGrabber 运行时提示空引用异常。如果我调试 sampleGrabber 它确实有接口(interface) ISampleGrabber 但是我不能再转换它了。将代码移动到运行图形的线程内允许我转换它,但它不适合我的应用程序。

如何通过将明显是 sampleGrabber 的内容转换为 ISampleGrabber 失败而出现空引用异常?

最佳答案

问题是 DirectShow 过滤器是早期的 COM 类,它们在引用计数、接口(interface)、名字对象、持久性方面实现了 COM 的一个子集——基本上所有的好东西都持续了多年——但它们完全忽略了公寓。 DirectShow 本身是多线程的,通常有一个控制线程,旁边还有工作流线程。 DirectShow 概念假设您可以轻松地在线程之间传递接口(interface)指针,并且不涉及、预期和必需的编码(marshal)处理。

然后出现了带有检查 COM 包装器的 .NET,DirectShow.NET 包装了接口(interface)指针,就好像它们是功能齐全的公寓感知 COM 指针一样。同时,Microsoft 停止提供 DirectShow 的更新(例如,为 Sample Grabber 提供免费的线程编码(marshal)拆收器),最终您在 .NET 上遇到了问题,您无法使用接口(interface)指针做一件本应简单的事情。

在 native 代码域中使用 API 仍然绝对没有问题,因为您可以跳过那里的编码(marshal)处理并使用直接指针。

您在一个公寓上构建图表,然后您从另一个公寓上的 Sample Grabber 收到回电(或者,在您的场景中,您只是在工作线程上做一些事情)。您不能使用原始接口(interface)指针,尤其是。成员变量中的那些,因为 .NET 运行时检查会遇到单元不匹配,尤其是尝试为另一个单元编码接口(interface)指针。

如果它是带有源代码的自定义过滤器,您可以添加自定义 IMarshal 实现或利用 free threaded marshaler修复 native 代码端的 .NET 问题,或者添加一个助手来跨公寓传递指针。

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

  • 在 MTA 工作,能够让多个线程访问 DirectShow 接口(interface)指针
  • 使用CLSID_FilterGraphNoThread Filter Graph Manager 版本
  • 在专用线程上初始化和终止过滤器图,在图操作期间分派(dispatch)窗口消息

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

关于c# - DirectShow 将 sampleGrabber 转换为 ISampleGrabber,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17282185/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com