0

我花了将近 4 个小时试图找出解决这个问题的方法。基本上,我正在使用DirectShowNet在 C# 中编写一个应用程序,该应用程序显示来自网络摄像头的视频,允许您拍摄快照并更改网络摄像头的分辨率。我有一个设备管理器,可以检测网络摄像头何时被拔出,然后重新插入。但是,在重新插入设备后,我很难重新创建图表。

我要做的第一件事是创建 FilterGraph 对象并将其转换为 IFilterGraph3。然后,我打这个电话:

graphBuilder.AddSourceFilterForMoniker(deviceMoniker, null, deviceName, out sourceFilter)

此调用在您最初启动应用程序时有效,即使您处理图表并创建一个新的也是如此。但是,唯一不起作用的是在重新插入设备后尝试创建图表时。

在一台机器(Win8 x64)上,我收到此错误:

REGDB_E_CLASSNOTREG - 0x80040154 - Class not registered

在另一台机器(Win7 x64)上,我收到此错误:

REGDB_E_IIDNOTREG - 0x80040155 - Interface not registered

我已经测试了将此代码构建为Any CPUx86。另外,我在其他机器上测试过,但独立于操作系统,我仍然得到接口未注册错误。我尝试过同时使用Logitech C920Microsoft LifeCam Studio。两者都会导致相同的错误。我也尝试了替代方法,使用 IMoniker 方法:

deviceMoniker.BindToObject(null, null, ref baseFilterId, out source);

发生同样的错误。我觉得在设备断开连接后可能会有一些东西我没有清理以允许图表正确抓取源(网络摄像头过滤器)。任何想法,将不胜感激。

一般 HRESULT 错误代码可在此处找到:COM 错误代码(通用)

4

1 回答 1

2

所以,基本上,我只是一天早上醒来,开始工作,盯着代码然后说,“等等,我知道为什么这不起作用......”。这是一个线程问题。我创建的初始图表与我稍后尝试创建的图表位于不同的线程上。这就是为什么它只在我重新创建图表时发生。

在应用程序启动后IVideoWindow's put_Owner插入设备时,我的方法也有问题。在这种情况下,设备在执行时没有被拔出,并且 put_Owner 会在尝试该方法时冻结/死锁。

总的来说,我有一个线程正在检测何时使用DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice). 因此,当我创建这些图表时,它们不在最初创建其他图表的主 UI 线程上。为了解决这个问题,我有我的类来处理设备接收,Action<Action> invoker它允许你提供一个方法包装器。在这种情况下,我将它传递Control.Invoke给 WinForms 表单,以便设备监视线程上的调用由 UI 线程中的此调用程序方法包装。完全解决了我的图表创建问题。

我非常惊讶以前没有人遇到过这种情况。在讨论与此错误相关的问题时,我找不到其他人提到线程。很奇怪。

于 2013-08-12T17:34:31.757 回答