Hangs on shutdown

Jun 3, 2010 at 8:28 PM

I've been struggling with this issue for some time now and was wondering if anyone else has experienced it. I'm using the VideoCaptureElement/Player to feed TV to my wpf app using various USB Tv tuners. When closing the app it hangs for a few minutes when trying to shutdown the tuner. Then the tuner then has to be physically unplugged and reinserted in order to play again.

The culprit is m_mediaControl.Stop() in the StopInternal() base class function. Is there anything I should be doing prior to calling Close() that will prevent this? Bypassing the StopInternal() altogther seems to help, but doesn't seem like a fix. Thanks, Mike

Coordinator
Jun 4, 2010 at 2:13 AM
If you just run Close() w/o closing the window, does your usb tuner turn off (sometimes the light will go out if it has a light on it) or does it do the same thing?

-Jer
Jun 4, 2010 at 5:00 AM

Calling Close() manually will shut the tuner down (light goes out) and it then lets me close the app gracefully. I'm guessing it's an issue with the canvas/window going away before the tuner has a chance to shutdown completely? Close() is currently getting called in the apps Dispose().

Coordinator
Jun 4, 2010 at 5:08 AM
What if you call the videoElement.Close() on the Window.Closing event?

-Jer
Jun 4, 2010 at 5:28 AM

No luck, still hangin. Maybe it's lower in the food chain. Could possibly the EVR be preventing the tuner from shutting down by going away prematurely? Thought I read somewhere where if buffers aren't flushed, or something to that effect, that the graph can lock up.. just a thought.

Coordinator
Jun 4, 2010 at 5:39 AM
I think the Close call is async...For testing purposes, can you put a Thread.Sleep(1000) in the Window.Closing event?
Jun 4, 2010 at 5:46 AM

Beat ya to it! That seems to work

Coordinator
Jun 4, 2010 at 5:50 AM
For a cleaner fix, do you think this would work?

Hook into the videoElement.MediaClosed event
On the window closing, run the videoElement.Close(), cancel the window closing via the args sent.
On the MediaClosed handler, close the window, making your you ignore the window.Closing handler.

Or maybe the Thread.Sleep is good enough ;)
Jun 4, 2010 at 5:50 AM

spoke too soon.. it works some of the time :)

Jun 4, 2010 at 5:58 AM

Ok, that works well. Thanks for the help, especially this late at night. So is it some race condition that's behind all of this?

Coordinator
Jun 4, 2010 at 6:02 AM
Sounds like it.  Can't really tell unless I got it in my debugger, but it surely seems like it's gacking when the window it's in no longer exists.  Maybe the updating of the video frames?  Anyways, glad its working for ya!

-Jer
Jun 4, 2010 at 4:25 PM

Just a side note, I came across a race condition in the Dispatcher implementation. The following code had a tendency to queue the method before the dispatcher had a chance to start a NEW thread and run the event loop..

public virtual void Play()
        {
            MediaPlayerBase.EnsureThread(DefaultApartmentState);
            System.Threading.Thread.Sleep(100); // The temp fix
            MediaPlayerBase.Dispatcher.BeginInvoke((Action)(delegate
            {
                MediaPlayerBase.Play();
                Dispatcher.BeginInvoke(((Action) (() => SetIsPlaying(true))));
            }));
        }

again, this is only the case when a new dispatcher thread had to be created. There is just enought time between the reset event and the running of the event loop that the queued method gets skipped at least until the next call to DoManagedMessageQueue(). If I get around to a permanent fix I'll be sure to post it.