我正在使用DirectShow的SampleGrabber从网络摄像头视频中捕获图像。代码使用C#编写,并使用DirectShow接口的.NET包装器进行COM通信。下面的BufferCB首先将图像数据复制到本地数组变量,禁用SampleGrabber回调,处理接收到的图像数据,并使用MessageBox显示结果。
public int BufferCB(double sampleTime, IntPtr pBuffer, int bufferLen)
{
if (Monitor.TryEnter(lockSync))
{
try
{
if ((pBuffer != IntPtr.Zero))
{
this.ImageData = new byte[bufferLen];
Marshal.Copy(pBuffer, this.ImageData, 0, bufferLen);
// Disable callback
sampleGrabber.SetCallback(null, 1);
// Process image data
var result = this.Decode(new Bitmap(this.ImageData));
if (result != null)
{
MessageBox.Show(result.ToString());
}
// Enable callback
sampleGrabber.SetCallback(this,1);
}
}
finally
{
Monitor.Exit(this.parent.lockSync);
}
}
return 0;
}
现在,如果
result = null
(因此MessageBox.Show从不运行),则两个夹紧调用sampleGrabber.SetCallback()都将运行,而不会出现任何问题。一旦result != null
和MessageBox显示出来,调用sampleGrabber.SetCallback(this,1)将引发InvalidCastException,如下所示:Unable to cast COM object of type 'System.__ComObject' to interface type 'DirectShowInterfaces.ISampleGrabber'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{6B652FFF-11FE-4FCE-92AD-0266B5D7C78F}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
如果我停在VS调试器中并添加
((ISampleGrabber)sampleGrabber).SetCallback(sampleGrabber, 1)
监视,则将收到ArgumentException,并显示消息“在对象实例上找不到方法”。代替。可能有人遇到同样的问题可以给我一些建议。谢谢。
最佳答案
BufferCB
和SampleCB
调用在通常属于MTA的辅助线程上进行。另一方面,您的图形初始化通常在STA线程上进行。 DirectShow API和过滤器主动忽略COM线程规则,而.NET强制执行线程检查会在尝试在错误的线程上使用COM接口指针时引发引发异常。您正在碰到这个问题。
您无需重置回调,然后再将其重新设置。改用SampleCB
回调,它作为阻塞调用发生。在完成处理之前,其余的流式传输将保留。
关于c# - DirectShow ISampleGrabber.SetCallback显示C#MessageBox后引发InvalidCastException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25392447/