ZeBobo5 / Vlc.DotNet

.NET control that hosts the audio/video capabilities of the VLC libraries
MIT License
948 stars 416 forks source link

crash on excessive video switching #621

Open GeorgeMaharis123 opened 4 years ago

GeorgeMaharis123 commented 4 years ago

I have an issue / a question (pick one) about Vlc.DotNet.

Generic information

Summary

I'm having issues with fast video switching/loading and stopping. My application plays a video (.mp4) for a given amount of time and then stops and shows nothing for the same amount of time and then restarts this loop. For example with this time set to 10 seconds, it will play the video for 10 sec, then blank for 10 sec, then again the video for 10 sec. Until it is stopped by the user or in this case a crash. The crash happens (with the play time set to 10sec) after 1-2 hours of looping. If the time is set to 1.5 seconds, it will crash in about 15 minutes.

I reported this bug to vlc/videolan: https://trac.videolan.org/vlc/ticket/22427 . Turns out the problem is not directly in VLC but in usage of VLC. As tigros999 commented on the issue, it can be bypassed in VLC.dotNet

I was able to reproduce this bug while letting the app run from VS debug for a long time breaking on all exceptions. The exception was: Managed Debugging Assistant 'LoaderLock?' Message=Managed Debugging Assistant 'LoaderLock?' : 'Attempting managed execution inside OS Loader lock. Do not attempt to run managed code inside a DllMain? or image initialization function since doing so can cause the application to hang.'

It was on myVlcInstance = new VlcInstance?(this, myLibraryLoader.GetInteropDelegate?<CreateNewInstance?>().Invoke(utf8Args.Length, utf8Args)); of Vlc.DotNet?.Core.Interops\VlcManager?.cs. Continuing execution got the C++ crash and app closed.

So from that I found this: ​https://stackoverflow.com/a/31322244/990618

VlcManager?.cs becomes:

...
private VlcLibraryLoader myLibraryLoader;
private VlcInstance myVlcInstance;
...
    ThreadStart threadRef = new ThreadStart(() =>
    {
        this.myLibraryLoader = VlcLibraryLoader.GetOrCreateLoader(dynamicLinkLibrariesPath);
    });
    Thread myThread = new Thread(threadRef);
    myThread.IsBackground = true;
    myThread.Start();
    myThread.Join();
...
    threadRef = new ThreadStart(() =>
    {
        myVlcInstance = new VlcInstance(this, myLibraryLoader.GetInteropDelegate<CreateNewInstance>().Invoke(utf8Args.Length, utf8Args));
    });
    myThread = new Thread(threadRef);
    myThread.IsBackground = true;
    myThread.Start();
    myThread.Join();                
jeremyVignelles commented 4 years ago

Please send me a minimal reproducing sample so I can check this out locally.

The code that was suggested doesn't feel like a proper fix for me: