我花了近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
我已经测试了将此代码构建为任何CPU 和 x86 。此外,我已在其他机器上测试过,但独立于操作系统,我仍然得到接口未注册错误。我尝试过同时使用Logitech C920和Microsoft LifeCam Studio。两者都会导致相同的错误。我也尝试过使用IMoniker方法的替代方法:
deviceMoniker.BindToObject(null, null, ref baseFilterId, out source);
发生同样的错误。我觉得在设备断开连接之后可能会出现一些问题,即我没有清理以使图形正确地抓取源(网络摄像头过滤器)。任何想法都将不胜感激。
可在此处找到常规HRESULT错误代码:COM Error Codes (Generic)
答案 0 :(得分:1)
所以,基本上,我只是在一天早上醒来,开始工作,盯着代码然后走了,“等等,我知道为什么这不起作用......”。这是线程问题。我创建的初始图形与我之后尝试创建的图形不同。这就是为什么它只在我重新创建图表时才会发生。
在应用程序启动后插入设备时,我遇到了IVideoWindow's put_Owner
方法的问题。在这种情况下,设备在执行时没有被拔掉,而put_Owner会在尝试该方法时冻结/死锁。
总的来说,我有一个线程正在检测何时使用DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice)
拔出/插入设备。因此,当我创建这些图形时,它们不在最初创建其他图形的主UI线程上。为了解决这个问题,我让我的类处理设备接受Action<Action> invoker
,它允许您提供方法包装器。在这种情况下,我传递WinForms表单的Control.Invoke
,以便设备监视线程上的调用由UI线程中的此调用方法包装。完全解决了我的图表创建问题。
我 非常惊讶 之前没有其他人遇到此事。在讨论与此错误相关的问题时,我找不到其他提及线程的人。很奇怪。