C# and vmem - what's wrong with this code?
Posted: 23 Aug 2010 13:26
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:
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!
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);
}));
}
}
What am I doing wrong?? Is there someone here who has successfully done this that can point me in the right direction?
Thanks!