嗨 Stack Overflow 成员,
我是 C# 编程的新手。我正在开发一个基本的相机流和仍然捕捉应用程序。一旦用户静止不动,我将使用 VMR9 的位图混合概念在叠加层上显示它。
我做了什么?
- 我从这里使用 C# 直接显示库
- 首先,我得到所有必需的过滤器接口。找到附加的捕获设备。调用带有源过滤器的渲染流和用于 PREVIEW 引脚的 vmr9。STILL PIN 的源过滤器、样本采集器和空渲染器。
- 我有三个菜单按钮-> 静止,显示覆盖和隐藏覆盖。
- 我正在使用该库中提供的位图混合器示例。
- 每次用户按下 Take Still 菜单时,图像将保存在桌面中,并将重新调整为小分辨率并显示在视频叠加层上。
- Show Overlay 和 hide Overlay 调用 ShowHideBitmap() 执行从 vmr9 过滤器查询 VMR9BitmapMixer 接口的操作,填充 VMR9AlphaBitmap 结构,然后调用 IVMRMixerBitmap9.SetAlphaBitmap 函数。
我面临什么问题?
- 拍摄静止图像后,如果我通过菜单选项调用 ShowHideBitmap(),拍摄的静止图像将在叠加层上完美更新。
- 这是另一种在保存静止图像后立即自动更新覆盖的选项。我创建了基于事件的线程,并让它等待使用 EventWaitHandle 创建的更新事件。在从 samplegrabber BufferCB 函数返回之前,我设置了这个更新事件。依次继续等待线程。在线程内部,我调用 ShowHideBitmap 函数。在这种情况下,我收到如下错误消息。
Unable to case COM object of type 'DirectShowLib.VideoMixingRenderer9' to interface type 'DirectShowLib.IVMRMixerBitmap9'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{ced175e5-1935-4820-81bd-ff6ad00c9108}' failed due to the following error: No such interface supported (Exception from HRESULT: 0X80040002 (E_NOINTERFACE)
这是 ShowHideBitmap 函数的代码块
//Declarations
private static IBaseFilter vmr9 = null;
private static IVMRMixerBitmap9 vmr9mixerBitmap = null;
private IVMRWindowlessControl9 vmr9windowlessCtrl = null;
private static void ShowHideBitmap(Boolean bEnable)
{
int hr = 0;
VMR9AlphaBitmap alphaBmp;
if (!bEnable)
{
if (vmr9mixerBitmap != null)
{
// Get current Alpha Bitmap Parameters
hr = vmr9mixerBitmap.GetAlphaBitmapParameters(out alphaBmp);
DsError.ThrowExceptionForHR(hr);
// Disable them
alphaBmp.dwFlags = VMR9AlphaBitmapFlags.Disable;
// Update the Alpha Bitmap Parameters
hr = vmr9mixerBitmap.UpdateAlphaBitmapParameters(ref alphaBmp);
DsError.ThrowExceptionForHR(hr);
// Create a surface from our alpha bitmap
surface.Dispose();
vmr9mixerBitmap = null;
//Release this alpha bitmap source.
if (alphaBitmap != null)
{
alphaBitmap.Dispose();
}
}
return;
}
else
{
try
{
alphaBitmap = BitmapGenerator.GenerateAlphaBitmap();
// Create a surface from our alpha bitmap
if(surface == null)
surface = new Surface(device, alphaBitmap, Pool.SystemMemory);
// Get the unmanaged pointer
unmanagedSurface = surface.GetObjectByValue(DxMagicNumber);
if (vmr9mixerBitmap == null)
vmr9mixerBitmap = (IVMRMixerBitmap9)vmr9;
// Set Alpha Bitmap Parameters for using a Direct3D surface
alphaBmp = new VMR9AlphaBitmap();
alphaBmp.dwFlags = VMR9AlphaBitmapFlags.EntireDDS;
alphaBmp.pDDS = unmanagedSurface;
alphaBmp.rDest = GetDestRectangle();
alphaBmp.fAlpha = 1.0f;
// Set Alpha Bitmap Parameters
hr = vmr9mixerBitmap.SetAlphaBitmap(ref alphaBmp);
DsError.ThrowExceptionForHR(hr);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
这是等待更新事件的线程。
Thread overlayupdatethreadhandle = new Thread(new ThreadStart(overlayupdatethread));
overlayupdatethreadhandle.Start();
private void overlayupdatethread()
{
do
{
overlayupdateeventhandle.WaitOne();
ShowHideBitmap(GlobalVar.m_ShowOverlay);
} while (true);
}
我尝试使用在后台以 100 毫秒间隔运行的计时器来更新此叠加层。使用 timer 效果很好,但对于这个操作,使用 timer 是一个不好的选择。所以我用线程概念移动。
为什么从线程调用时获取接口失败,而从菜单选项调用时效果很好?我应该照顾任何特殊的事情吗?我什至尝试过参数化线程,但没有运气。
在此先感谢您的帮助。
编辑:如果从主线程调用 ShowHideBitmap,则一切正常。如果从工作线程调用 ShowHideBitmap,COM 对象会创建异常。如何处理这种跨线程操作?