views:

597

answers:

2

Hi-

I'm working on implementing directshow capability in a C# dll. I'm basing my work off of the C++ based "CameraCapture" example Microsoft provides with the Windows Mobile 6 sdk. Things were going well (thanks to earlier help on this site), but I've run into a bit of a snag while trying to listen for directshow events in C# land:

I have a thread that loops to listen for dshow events. It waits based on a manual reset event that gets defined here (this is defined at the end of graph initialization: the graph is built, renderstream is called, and controlstream is already blocking dataflow):

DshowRequestMan = new ManualResetEvent(false);
MediaEvent = (IMediaEvent)FilterGraph;                
chk(MediaEvent.GetEventHandle(out DshowEventHandle));
DshowRequestMan.Handle = DshowEventHandle; //note: no "SafeHandle" in cf

There are 2 related problems I'm experiencing with this:

  1. When my dshow event handler loop pulls the event via IMediaEvent.GetEvent() using a timeout of 0, I get a "timeout exceeded" hresult (-2147467260) on the third iteration. That third event trigger (and subsequent error) don't occur in the C++ example.
  2. If I ignore the timeout case mentioned above, it will constantly trigger with a 73 event. This kills the processor since the loop basically never pauses.

When the C++ example runs its graph in preview mode, it gets two IMediaEvents: first 13, then 73. After that, it stops triggering until actual capturing is started. My C# version pulls 13, then 73, then 73 again, but with the timeout error.

In short, it seems like that third triggering of the DshowRequestMan shouldn't be happening because there is no dshowevent to actually "get", hence, the timeout.

Not sure what I'm doing wrong- I'm calling "FreeEventParams()" with each iteration... I'm suspecting the ManualResetEvent object is being used incorrectly since I'm just assigning something to its handle property, but the same thing happens when I use a Pinvoked "WaitForSingleObject" to listen to the DshowEventHandle... I'm confused at this point.

Any ideas would be greatly appreciated. Thanks in advance!

A: 

Are you making sure to Reset you event after you get and handle it?

heavyd
Yup- DshowRequestMan.Reset() gets called at the bottom of the loop. I also tried it without calling Reset- both had the same result.
A: 

Whatr does your actual wait code look like? The problem is likely that you're waiting for 0ms, which basically means "check the event and return immediately." If you want it to block on the wait (like a native call with WAIT_INFINITE) you need to pass in System.Threading.Timeout.Infinite (which is actually -1).

If you want the checking thread to periodically yield (which is way safer than an infinite wait and will actually allow your app to shut down), then you need to check the return from the wait, and if it's a timeout (0x80004004) then just go back and wait again:

while(!shutdown)
{
  if(DshowRequestMan.WaitOne(1000))
  {
    // handle the event
  }
}
ctacke