显示C#MessageBox后,DirectShow ISampleGrabber.SetCallback抛出InvalidCastException

时间:2014-08-19 20:30:27

标签: c# com directshow directshow.net

我正在使用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)的监视,我将得到带有&#34的消息的ArgumentException;无法在对象实例上找到该方法。"代替。

可能有人遇到同样的问题可以给我一些建议。谢谢。

1 个答案:

答案 0 :(得分:2)

BufferCBSampleCB调用发生在工作线程上,工作线程通常属于MTA。另一方面,您的图初始化通常发生在STA线程上。 DirectShow API和过滤器挥发性地忽略COM线程规则,而.NET强制执行线程检查尝试在错误的线程上使用COM接口指针时引发异常。你正在解决这个问题。

您无需重置回调,然后将其重新设置。改为使用SampleCB回调,它会作为阻止调用发生。在您完成处理之前,剩余的流媒体将处于暂停状态。