c#compact框架中的Directshow:Filtergraph'的触发器处理问题;伊梅迪亚事件
我正在致力于在C#dll中实现directshow功能。我的工作基于C++提供的“CasaCaspAccess”示例,微软提供了Windows Mobile 6 SDK。 事情进行得很顺利(多亏了本网站早些时候的帮助),但我在尝试收听C#land的directshow活动时遇到了一些障碍: 我有一个线程,可以循环侦听dshow事件。它根据此处定义的手动重置事件进行等待(这是在图形初始化结束时定义的:图形已生成,renderstream已调用,controlstream已阻止数据流): 我在这方面遇到了两个相关问题:c#compact框架中的Directshow:Filtergraph'的触发器处理问题;伊梅迪亚事件,c#,com,compact-framework,directshow,C#,Com,Compact Framework,Directshow,我正在致力于在C#dll中实现directshow功能。我的工作基于C++提供的“CasaCaspAccess”示例,微软提供了Windows Mobile 6 SDK。 事情进行得很顺利(多亏了本网站早些时候的帮助),但我在尝试收听C#land的directshow活动时遇到了一些障碍: 我有一个线程,可以循环侦听dshow事件。它根据此处定义的手动重置事件进行等待(这是在图形初始化结束时定义的:图形已生成,renderstream已调用,controlstream已阻止数据流): 我在这方面
当C++示例在预览模式下运行它的图形时,它会得到两个IimeAdvices事件:第一个13,然后73个。之后,它停止触发,直到实际捕获开始。我的C#版本拉了13次,然后是73次,然后又拉了73次,但出现了超时错误
简言之,似乎DshowRequestMan的第三次触发不应该发生,因为没有真正“获取”的dshowevent,因此超时 不确定我做错了什么-我在每次迭代中调用“FreeEventParams()”。。。我怀疑ManualResetEvent对象被错误地使用,因为我只是给它的handle属性赋值,但当我使用Pinvoked“WaitForSingleObject”来侦听DshowEventHandle时,也会发生同样的情况。。。我在这一点上感到困惑任何想法都将不胜感激。提前谢谢 您是否确保在获得并处理事件后重置事件 您的实际等待代码是什么样子的?问题很可能是您正在等待0ms,这基本上意味着“检查事件并立即返回”。如果您希望它在等待时阻塞(如使用wait_INFINITE的本机调用),则需要传入System.Threading.Timeout.INFINITE(实际上是-1) 如果您希望检查线程周期性地产生(这比无限等待安全得多,并且实际上会允许您的应用程序关闭),那么您需要检查等待的返回,如果是超时(0x80004004),则只需返回并再次等待:
while(!shutdown)
{
if(DshowRequestMan.WaitOne(1000))
{
// handle the event
}
}
以下是我的过滤器图事件处理代码:
while (!_stopReceivingEvents) {
IntPtr eventHandle;
var hr = _mediaEvent.GetEventHandle(out eventHandle);
DsError.ThrowExceptionForHR(hr);
//NOTE: Do not close the event handle, because it is used internally by the filter graph
using (var safeWaitHandle = new SafeWaitHandle(eventHandle, false)) {
using (var waitHandle = new AutoResetEvent(false) {SafeWaitHandle = safeWaitHandle}) {
if (WaitHandle.WaitAll(new[] {waitHandle}, 500)) {
//receive all available events
do {
EventCode eventCode;
IntPtr param1;
IntPtr param2;
hr = _mediaEvent.GetEvent(out eventCode, out param1, out param2, 500);
_mediaEvent.FreeEventParams(eventCode, param1, param2);
if (hr == 0) {
switch (eventCode) {
//add handling code here
}
}
} while (hr == 0);
}
}
}
}
在循环的底部调用-DshowRequestMan.Reset()。我也试过了,没有调用Reset-两个都有相同的结果。谢谢你的代码块+1。我有一个与此相关的问题。我将您的代码粘贴在
hr=mediaControl.Run()行之后代码>因为它是一个while
所以代码在内部执行,而和预览窗口永远不会显示。因此,我将while
循环包装在System.Threading.Tasks.Task.Factory.StartNew(()=>{//while loop})中代码>。因为我是Directshow
和.NET
的新手,所以我想问一下,在任务中保持是安全的,或者你会建议的任何其他选项?有什么帮助吗?对不起,我不太清楚这段代码是做什么的。那是很久以前的事了。
while (!_stopReceivingEvents) {
IntPtr eventHandle;
var hr = _mediaEvent.GetEventHandle(out eventHandle);
DsError.ThrowExceptionForHR(hr);
//NOTE: Do not close the event handle, because it is used internally by the filter graph
using (var safeWaitHandle = new SafeWaitHandle(eventHandle, false)) {
using (var waitHandle = new AutoResetEvent(false) {SafeWaitHandle = safeWaitHandle}) {
if (WaitHandle.WaitAll(new[] {waitHandle}, 500)) {
//receive all available events
do {
EventCode eventCode;
IntPtr param1;
IntPtr param2;
hr = _mediaEvent.GetEvent(out eventCode, out param1, out param2, 500);
_mediaEvent.FreeEventParams(eventCode, param1, param2);
if (hr == 0) {
switch (eventCode) {
//add handling code here
}
}
} while (hr == 0);
}
}
}
}