Page 1 of 1

C# and vmem - what's wrong with this code?

Posted: 23 Aug 2010 13:26
by am70
I'm attempting to write a small C# class that will return a WriteableBitmap that's hooked to the output of a VLC instance via vmem. VLC starts up, calls the dolock() function once, then immediately crashes reporting an error in libswscale_plugin.dll.

Here's the relevant code:

Code: Select all

static class render { static Dispatcher dispatcher = Dispatcher.CurrentDispatcher; [UnmanagedFunctionPointer(CallingConvention.Cdecl)] unsafe delegate IntPtr CLock(IntPtr ctx); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] unsafe delegate void CUnLock(IntPtr ctx); static CLock _lock; static CUnLock _unlock; static IntPtr pix_ptr; static WriteableBitmap wbmp; static int _w, _h; static VideoLanClient Vlc; static VlcMediaPlayer VlcPlayer; public static BitmapSource start(string mrl, int w, int h) { _w = w; _h = h; wbmp = new WriteableBitmap(_w, _h, 96, 96, PixelFormats.Bgr32, null); pix_ptr = Marshal.AllocHGlobal(_w * _h * 4); _lock += do_lock; _unlock += do_unlock; string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); string[] args = new string[] { @"--vout=vmem", @"--vmem-width=" + _w.ToString(), @"--vmem-height=" + _h.ToString(), @"--vmem-pitch=" + (_w * 4).ToString(), @"--vmem-chroma=RV32", @"--vmem-lock=" + Marshal.GetFunctionPointerForDelegate(_lock).ToInt32().ToString(), @"--vmem-unlock=" + Marshal.GetFunctionPointerForDelegate(_unlock).ToInt32().ToString(), @"--vmem-data=" + pix_ptr.ToInt32().ToString() }; Vlc = new VideoLanClient(path, args); VlcPlayer = Vlc.NewMediaPlayer(IntPtr.Zero); VlcMedia desc = Vlc.NewMedia(mrl); VlcPlayer.Load(desc); desc.Dispose(); VlcPlayer.Play(); return wbmp; } static IntPtr do_lock(IntPtr ctx) { return ctx; } static void do_unlock(IntPtr ctx) { dispatcher.Invoke(DispatcherPriority.Render, new Action(delegate() { wbmp.WritePixels(new System.Windows.Int32Rect(0, 0, _w, _h), ctx, wbmp.BackBufferStride, 0); })); } }
If I remove the vmem command-line argument, the file plays just fine in a desktop window.

What am I doing wrong?? Is there someone here who has successfully done this that can point me in the right direction?

Thanks!

Re: C# and vmem - what's wrong with this code?

Posted: 23 Aug 2010 19:30
by RĂ©mi Denis-Courmont
It's crashing because you're not correct functions pointers or video memory pointers.

Re: C# and vmem - what's wrong with this code?

Posted: 24 Aug 2010 02:40
by am70
It's crashing because you're not correct functions pointers or video memory pointers.
Forgive my ignorance, but I'm not fluent in C++, so most of the sample code is useless to me. It seems my understanding of how this works is incorrect, conceptually.

Can you explain specifically what I'm doing incorrectly?

1. Allocate a video buffer where size = width * height * bytes per pixel;
2. Pass a pointer to the buffer to VLC using the vmem-data argument;
3. Pass pointers to my lock and unlock functions to VLC using the vmem-lock and vmem-unlock arguments;
4. When a video frame is about to be decoded, VLC calls my lock function with a pointer to the buffer (from vmem-data);
5. I return the same pointer back to VLC (because my data structure is only video memory, no other fields);
6. VLC renders the video frame into the buffer;
7. VLC calls my unlock function which displays the image.

From debugging I know that:

1. VLC is calling my lock function as expected;
2. The pointer that VLC is passing to the lock function is the same as the pointer passed via vmem-data.

I'm reasonably confident that at least this part is correct. So what is it exactly that VLC expects that I'm not giving it?

Thanks for your help.

Re: C# and vmem - what's wrong with this code?

Posted: 24 Aug 2010 08:40
by am70
It's crashing because you're not correct functions pointers or video memory pointers.
Actually it turns out my code was fine. It works fine with 0.9.9, but produces the libswscale_plugin crash with 1.0.x.

Does anyone have a clue why this might be?