Page 1 of 1

libvlc events makes vshost crash (C#)

Posted: 27 Jul 2010 04:34
by dyster_
My project: automatic snapshot generator, mostly for the fun of it.

First I looked about for a nice C# wrapper, and for 1.1.x, there is only libvlcnet. A nice and nifty project that, allthough a bit too complex for my needs, but I tried it anyway.
They have a readymade VlcControl, just drag and drop, so that's what I did and hit Debug. And BAM vshost32.exe crashes, and it's really hard to debug something when it's the debugger who has crashed. (running it without debugger just makes it crash).
Well so I gave up instantly and decided to just make my own wrapper. I put in all the basic stuff and had a crude but working vlc clone. Then I came to the point where it was time to attach event handlers, and thats where I encountered the very same problem. Attaching events works fine, but as soon as an event is triggered, vshost32 crashes, even if the callback method is empty so it shouldn't be thread related, which was my first guess.
Vlc version 1.1.1 The luggage

Invokes:

Code: Select all

public delegate void EventCallbackDelegate(IntPtr userdata); [DllImport("libvlc")] public static extern IntPtr libvlc_media_player_event_manager(IntPtr player); [DllImport("libvlc")] public static extern int libvlc_event_attach(IntPtr p_event_manager, libvlc_event_type_t i_event_type, EventCallbackDelegate f_callback, IntPtr userdata);
Typedef

Code: Select all

internal enum libvlc_event_type_t { libvlc_MediaMetaChanged = 0, libvlc_MediaSubItemAdded, libvlc_MediaDurationChanged, libvlc_MediaParsedChanged, libvlc_MediaFreed, libvlc_MediaStateChanged, libvlc_MediaPlayerMediaChanged = 0x100, libvlc_MediaPlayerNothingSpecial, // and so on, you get the idea }

Code: Select all

IntPtr instance, player; private void Init() { string[] args = new[] { "-I", "dummy", "--ignore-config", @"--plugin-path=C:\Program Files (x86)\VideoLAN\VLC\plugins", "--vout-filter=deinterlace", "--deinterlace-mode=blend" }; instance = LibVlc.libvlc_new(args.Length, args); IntPtr media = LibVlc.libvlc_media_new_path(instance, @"somefile"); IntPtr eventManager = LibVlc.libvlc_media_player_event_manager(player); LibVlc.libvlc_event_attach(eventManager, LibVlc.libvlc_event_type_t.libvlc_MediaPlayerPaused, MediaPlayerPaused, IntPtr.Zero); } private void MediaPlayerPaused(IntPtr userdata) { //listBox1.Items.Add("Player paused"); }
I'm not sure if this is the right place to post this, or even the right forum, but I have to go somewhere =)
I realise that it's hard for anyone to come with a magic answer, but any pointer would be appreciated, because I am completely lost right now.

Re: libvlc events makes vshost crash (C#)

Posted: 27 Jul 2010 17:41
by RĂ©mi Denis-Courmont
This smells like a calling convention error. And yes, providing managed code callbacks to native code is notoriously difficult.

Re: libvlc events makes vshost crash (C#)

Posted: 28 Jul 2010 05:04
by dyster_
This smells like a calling convention error. And yes, providing managed code callbacks to native code is notoriously difficult.
It was indeed! Digging into the matter (msdn, who actually produced answers for once) I found that my code was lacking this (first line):

Code: Select all

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void EventCallbackDelegate(IntPtr userdata);
There is also a convention for winapi, which seems to be the default then, since this is not needed when hooking global windows events =)
I also noticed today that I had forgotten the libvlc_event_t parameter for my callback method, but this doesn't seem to matter.

And thirdly I discovered another interesting thing, like in my code, you normally don't declare and save the delegate when registering an event, you point it directly to the callback and the rest is handled by the compiler.
But when you're sending it away with pinvoke, there is no reference left to the delegate, and it gets wiped by the garbage collector that normally is your best friend =)

Thank you for your answer that was actually right on the spot.

Re: libvlc events makes vshost crash (C#)

Posted: 18 Aug 2010 00:56
by Translucent
How did you get this to work? I've been trying the same thing for a while now with no luck what so ever


[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void EventCallbackDelegate(IntPtr userdata);

[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_media_player_event_manager")]
public static extern IntPtr libvlc_media_player_event_manager(IntPtr player);

[DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_event_attach")]
public static extern void libvlc_event_attach(IntPtr p_event_manager, VlcEventType i_event_type, EventCallbackDelegate f_callback, IntPtr p_user_data);

private void MediaPlayerEnded(IntPtr userdata)
{
System.Windows.Forms.MessageBox.Show("Video is ended");
}

public void InitalizeEvents()
{
VLCLib.EventCallbackDelegate callback = new VLCLib.EventCallbackDelegate(MediaPlayerEnded);
AttachEvent(VlcEventType.MediaPlayerEndReached, callback, IntPtr.Zero);
}

This doesn't work for me, I keep getting a Microsoft Visual C++ Runtime Library error

Assertion failed!
Program:...
File: ../../../src/control/event.c
Line: 362

Expression: 0

Any idea what this is about or how to get past it?

Re: libvlc events makes vshost crash (C#)

Posted: 18 Aug 2010 22:05
by Translucent
Ok further digging shows that the event_type is bad and/or unknown. How is this possible? I'm using an enum so the event type value should be '0' or zero. This is the first event listen in the c code of the vlc_event_type_t enum for state changes. Has anyone gotten events to work in c# at or after 1.0.0? And if so could I please get some help tracking down the issue?

Re: libvlc events makes vshost crash (C#)

Posted: 15 Dec 2010 22:29
by hussam_2000
Any luck in here ? I need some help. Thank you

Re: libvlc events makes vshost crash (C#)

Posted: 18 Dec 2010 00:18
by dyster_
Sorry for the late reply, I'm used to forums sending me mails when I get a reply, here is what I think is a working sample, it's been a while since I fiddled with this.
Translucent you haven't included sample code for the libvlc_event_type_t, which seems to be your problem, if you're good at transposing from ++ to # you can just copy my code, I'm fairly certain this worked for me.

Code: Select all

private IntPtr instance, player; private LibVlc.EventCallbackDelegate _pausedDelegate; private LibVlc.EventCallbackDelegate _playingDelegate; public Form1() { string[] args = new[] { "-I", "dummy", "--ignore-config", @"--plugin-path=C:\Program Files (x86)\VideoLAN\VLC\plugins", "--vout-filter=deinterlace", "--deinterlace-mode=blend" }; instance = LibVlc.New(args.Length, args); player = LibVlc.MediaPlayerNew(instance); IntPtr eventManager = LibVlc.MediaPlayerEventManager(player); _pausedDelegate = new LibVlc.EventCallbackDelegate(MediaPlayerPaused); _playingDelegate = new LibVlc.EventCallbackDelegate(MediaPlayerPlaying); LibVlc.EventAttach(eventManager, LibVlc.libvlc_event_type_t.libvlc_MediaPlayerPaused, _pausedDelegate, IntPtr.Zero); LibVlc.EventAttach(eventManager, LibVlc.libvlc_event_type_t.libvlc_MediaPlayerPlaying, _playingDelegate, IntPtr.Zero); } private void MediaPlayerPlaying(IntPtr userdata) { // play } private void MediaPlayerPaused(IntPtr userdata) { // pause } namespace LibVlc { [DllImport("libvlc", EntryPoint = "libvlc_event_attach")] public static extern int EventAttach(IntPtr pEventManager, libvlc_event_type_t iEventType, EventCallbackDelegate fCallback, IntPtr userdata); [DllImport("libvlc", EntryPoint = "libvlc_media_player_event_manager")] public static extern IntPtr MediaPlayerEventManager(IntPtr player); [DllImport("libvlc", EntryPoint = "libvlc_new")] public static extern IntPtr New(int argc, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[] argv); [DllImport("libvlc", EntryPoint = "libvlc_media_player_new")] public static extern IntPtr MediaPlayerNew(IntPtr instance); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void EventCallbackDelegate(IntPtr userdata); internal enum libvlc_event_type_t { libvlc_MediaMetaChanged = 0, libvlc_MediaSubItemAdded, libvlc_MediaDurationChanged, libvlc_MediaParsedChanged, libvlc_MediaFreed, libvlc_MediaStateChanged, libvlc_MediaPlayerMediaChanged = 0x100, libvlc_MediaPlayerNothingSpecial, libvlc_MediaPlayerOpening, libvlc_MediaPlayerBuffering // and so on and so on... } }

Re: libvlc events makes vshost crash (C#)

Posted: 28 Dec 2010 20:52
by hussam_2000
Thank you so much for the help.I was away on sick leave and i just got the chance to try it today. i tried it and it still doesn't work for me :( nothing happenes for me . i wonder why ? im using 1.1.4 so i dont know if that is the problem ?

Re: libvlc events makes vshost crash (C#)

Posted: 28 Dec 2010 20:55
by hussam_2000
does this code has to happen in my Form class ? im doing all of it in a seprate class other than my Form class. Thank you

Re: libvlc events makes vshost crash (C#)

Posted: 15 Jun 2012 13:45
by moffata2
Hi all,

I need help too getting these events working, I know its an old thread so this is a bit of a shot in the dark!!

here,s my code

VlcInstance instance;
VlcMediaPlayer player;



private unsafe LibVlc.EventCallbackDelegate _stoppedDelegated;



public Form1()
{
InitializeComponent();

openFileDialog1.FileName = "";
openFileDialog1.Filter = "MPEG, AVI|*.mpg;*.avi|All|*.*";

string[] args = new string[] {
"-I", "dummy", "--ignore-config",
@"--plugin-path=C:\Program Files\VideoLAN\VLC\plugins"
//,"--vout-filter=deinterlace", "--deinterlace-mode=blend"
};

instance = new VlcInstance(args);

var player = LibVlc.MediaPlayerNew(instance.Handle);


IntPtr eventManager = LibVlc.MediaPlayerEventManager(player);

_stoppedDelegated = new LibVlc.EventCallbackDelegate(MediaPlayerStopped);


LibVlc.EventAttach(eventManager, LibVlc.libvlc_event_type_t.libvlc_MediaPlayerEndReached, _stoppedDelegated, IntPtr.Zero);



}


private void MediaPlayerStopped(IntPtr userdata)
{
MessageBox.Show("Yippee!!");
}

And The VLC class

[DllImport("libvlc", EntryPoint = "libvlc_event_attach")]
public static extern int EventAttach(IntPtr pEventManager, libvlc_event_type_t iEventType,
EventCallbackDelegate fCallback, IntPtr userdata);

[DllImport("libvlc", EntryPoint = "libvlc_media_player_event_manager")]
public static extern IntPtr MediaPlayerEventManager(IntPtr player);

[DllImport("libvlc", EntryPoint = "libvlc_new")]
public static extern IntPtr New(int argc, [MarshalAs(UnmanagedType.LPArray,
ArraySubType = UnmanagedType.LPStr)] string[] argv);

[DllImport("libvlc", EntryPoint = "libvlc_media_player_new")]
public static extern IntPtr MediaPlayerNew(IntPtr instance);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void EventCallbackDelegate(IntPtr userdata);

[DllImport("libvlc", EntryPoint = "libvlc_errmsg")]
public static extern IntPtr Error();



internal enum libvlc_event_type_t
{
libvlc_MediaMetaChanged = 0,
libvlc_MediaSubItemAdded,
libvlc_MediaDurationChanged,
libvlc_MediaParsedChanged,


My events are not firing!! I'm new to interops and this is my first task!!

Thanks in advance!! :)