Commit 77aa5b9e authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Switch CIL bindings to libvlc API

parent c39f7535
CS = gmcs
CS = gmcs -codepage:utf8
CSFLAGS =
TARGETS = VideoLAN.VLC.Control.dll testvlc.exe
......@@ -6,9 +6,9 @@ TARGETS = VideoLAN.VLC.Control.dll testvlc.exe
all: $(TARGETS)
clean:
rm -f -- $(TARGETS) *.netmodule
rm -f -- $(TARGETS) *.netmodule *~
VideoLAN.VLC.Control.dll: marshal.cs libvlc.cs exception.cs
VideoLAN.VLC.Control.dll: marshal.cs ustring.cs exception.cs libvlc.cs
testvlc.exe: testvlc.cs VideoLAN.VLC.Control.dll
%.netmodule: %.cs Makefile
......
......@@ -22,111 +22,73 @@
**********************************************************************/
using System;
using System.Runtime.InteropServices;
namespace VideoLAN.VLC
namespace VideoLAN.LibVLC
{
/**
* Base class for managed LibVLC exceptions
* VLCException: managed base class for LibVLC exceptions
*/
public class MediaException : Exception
public class VLCException : Exception
{
public MediaException ()
public VLCException ()
{
}
public MediaException (string message)
public VLCException (string message)
: base (message)
{
}
public MediaException (string message, Exception inner)
public VLCException (string message, Exception inner)
: base (message, inner)
{
}
};
public class PositionKeyNotSupportedException : MediaException
{
public PositionKeyNotSupportedException ()
{
}
public PositionKeyNotSupportedException (string message)
: base (message)
{
}
public PositionKeyNotSupportedException (string message, Exception inner)
: base (message, inner)
{
}
};
public class PositionOriginNotSupportedException : MediaException
{
public PositionOriginNotSupportedException ()
{
}
public PositionOriginNotSupportedException (string message)
: base (message)
{
}
public PositionOriginNotSupportedException (string message, Exception inner)
: base (message, inner)
{
}
};
public class InvalidPositionException : MediaException
{
public InvalidPositionException ()
{
}
public InvalidPositionException (string message)
: base (message)
{
}
public InvalidPositionException (string message, Exception inner)
: base (message, inner)
{
}
};
public class PlaylistException : MediaException
/**
* libvlc_exception_t: structure for unmanaged LibVLC exceptions
*/
[StructLayout (LayoutKind.Sequential)]
internal sealed class NativeException : IDisposable
{
public PlaylistException ()
{
}
int raised;
int code;
IntPtr message;
public PlaylistException (string message)
: base (message)
{
}
[DllImport ("libvlc-control.dll", EntryPoint="libvlc_exception_init")]
static extern void Init (NativeException e);
[DllImport ("libvlc-control.dll", EntryPoint="libvlc_exception_clear")]
static extern void Clear (NativeException e);
/*[DllImport ("libvlc-control.dll",
EntryPoint="libvlc_exception_raised")]
static extern int Raised (NativeException e);*/
[DllImport ("libvlc-control.dll",
EntryPoint="libvlc_exception_get_message")]
static extern IntPtr GetMessage (NativeException e);
public PlaylistException (string message, Exception inner)
: base (message, inner)
public NativeException ()
{
Init (this);
}
};
public class InternalException : MediaException
{
public InternalException ()
{
}
public InternalException (string message)
: base (message)
public void Raise ()
{
try
{
string msg = U8String.FromNative (GetMessage (this));
if (msg != null)
throw new VLCException (msg);
}
finally
{
Clear (this);
}
}
public InternalException (string message, Exception inner)
: base (message, inner)
public void Dispose ()
{
Clear (this);
}
};
};
......@@ -24,225 +24,94 @@
using System;
using System.Runtime.InteropServices;
namespace VideoLAN.VLC
namespace VideoLAN.LibVLC
{
public class MediaControl : IDisposable
/** Safe handle for unmanaged LibVLC instance pointer */
internal sealed class InstanceHandle : NonNullHandle
{
/**
* Possible player status
*/
enum PlayerStatus
{
PlayingStatus,
PauseStatus,
ForwardStatus,
BackwardStatus,
InitStatus,
EndStatus,
UndefinedStatus,
};
enum PositionOrigin
private InstanceHandle ()
{
AbsolutePosition,
RelativePosition,
ModuloPosition,
};
}
enum PositionKey
{
ByteCount,
SampleCount,
MediaTime,
};
[DllImport ("libvlc-control.dll", EntryPoint="libvlc_new")]
public static extern
InstanceHandle Create (int argc, U8String[] argv, NativeException ex);
MediaControlHandle self;
[DllImport ("libvlc-control.dll", EntryPoint="libvlc_destroy")]
static extern void Destroy (InstanceHandle ptr, NativeException ex);
private void CheckDisposed ()
protected override bool ReleaseHandle ()
{
if (self.IsInvalid)
throw new ObjectDisposedException ("Media controlled disposed");
Destroy (this, null);
return true;
}
};
/**
* Creates a MediaControl with a new LibVLC instance
*/
public MediaControl (string[] args)
{
NativeException e = NativeException.Prepare ();
public class VLCInstance : IDisposable
{
NativeException ex;
InstanceHandle self;
public VLCInstance (string[] args)
{
U8String[] argv = new U8String[args.Length];
for (int i = 0; i < args.Length; i++)
argv[i] = new U8String (args[i]);
self = MediaControlAPI.New (argv.Length, argv, ref e);
e.Consume ();
}
/**
* Creates a MediaControl from an existing LibVLC instance
*/
/*public MediaControl (MediaControl instance)
{
NativeException e = NativeException.Prepare ();
IntPtr libvlc = mediacontrol_get_libvlc_instance (instance.self);
self = mediacontrol_new_from_instance (libvlc, ref e);
e.Consume ();
}*/
/*public void Play (from)
{
CheckDisposed ();
throw new NotImplementedException ();
}*/
public void Resume ()
{
CheckDisposed ();
NativeException e = NativeException.Prepare ();
MediaControlAPI.Resume (self, IntPtr.Zero, ref e);
e.Consume ();
ex = new NativeException ();
self = InstanceHandle.Create (argv.Length, argv, ex);
ex.Raise ();
}
public void Pause ()
{
CheckDisposed ();
NativeException e = NativeException.Prepare ();
MediaControlAPI.Pause (self, IntPtr.Zero, ref e);
e.Consume ();
}
public void Stop ()
public void Dispose ()
{
CheckDisposed ();
NativeException e = NativeException.Prepare ();
MediaControlAPI.Stop (self, IntPtr.Zero, ref e);
e.Consume ();
ex.Dispose ();
self.Close ();
}
public void AddItem (string mrl)
public MediaDescriptor CreateDescriptor (string mrl)
{
CheckDisposed ();
U8String umrl = new U8String (mrl);
DescriptorHandle dh = DescriptorHandle.Create (self, umrl, ex);
ex.Raise ();
U8String nmrl = new U8String (mrl);
NativeException e = NativeException.Prepare ();
MediaControlAPI.PlaylistAddItem (self, nmrl, ref e);
e.Consume ();
return new MediaDescriptor (dh);
}
};
public void Clear ()
/** Safe handle for unmanaged LibVLC media descriptor */
internal sealed class DescriptorHandle : NonNullHandle
{
private DescriptorHandle ()
{
CheckDisposed ();
NativeException e = NativeException.Prepare ();
MediaControlAPI.PlaylistClear (self, ref e);
e.Consume ();
}
public string[] Playlist
{
get
{
CheckDisposed ();
throw new NotImplementedException ();
}
}
[DllImport ("libvlc-control.dll",
EntryPoint="libvlc_media_descriptor_new")]
public static extern
DescriptorHandle Create (InstanceHandle inst, U8String mrl,
NativeException ex);
/**
* Switches to the next playlist item
*/
public void NextItem ()
{
CheckDisposed ();
[DllImport ("libvlc-control.dll",
EntryPoint="libvlc_media_descriptor_release")]
public static extern void Release (DescriptorHandle ptr);
NativeException e = NativeException.Prepare ();
MediaControlAPI.PlaylistNextItem (self, ref e);
e.Consume ();
}
/**
* Normalized audio output volume in percent (must be [0..100]).
*/
public short SoundVolume
protected override bool ReleaseHandle ()
{
get
{
CheckDisposed ();
NativeException e = NativeException.Prepare ();
short vol = MediaControlAPI.SoundGetVolume (self, ref e);
e.Consume ();
return vol;
}
set
{
CheckDisposed ();
if ((value < 0) || (value > 100))
throw new ArgumentOutOfRangeException ("Volume not within [0..100]");
NativeException e = NativeException.Prepare ();
MediaControlAPI.SoundSetVolume (self, value, ref e);
e.Consume ();
}
}
/**
* Performance speed rate in percent.
*/
public int Rate
{
get
{
CheckDisposed ();
NativeException e = NativeException.Prepare ();
int rate = MediaControlAPI.GetRate (self, ref e);
e.Consume ();
return rate;
}
set
{
CheckDisposed ();
NativeException e = NativeException.Prepare ();
MediaControlAPI.SetRate (self, value, ref e);
e.Consume ();
}
Release (this);
return true;
}
};
/**
* Fullscreen flag.
*/
public bool Fullscreen
{
get
{
CheckDisposed ();
NativeException e = NativeException.Prepare ();
int ret = MediaControlAPI.GetFullscreen (self, ref e);
e.Consume ();
return ret != 0;
}
set
{
CheckDisposed ();
NativeException e = NativeException.Prepare ();
MediaControlAPI.SetFullscreen (self, value ? 1 : 0, ref e);
e.Consume ();
}
}
public class MediaDescriptor
{
NativeException ex;
DescriptorHandle self;
public void Dispose ()
internal MediaDescriptor (DescriptorHandle self)
{
self.Dispose ();
this.self = self;
ex = new NativeException ();
}
};
};
......@@ -24,49 +24,8 @@
using System;
using System.Runtime.InteropServices;
namespace VideoLAN.VLC
namespace VideoLAN.LibVLC
{
internal class MediaControlAPI
{
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_new")]
public static extern MediaControlHandle New (int argc, U8String[] argv, ref NativeException e);
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_exit")]
public static extern void Exit (IntPtr self);
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_start")]
public static extern void Start (MediaControlHandle self, IntPtr pos, ref NativeException e);
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_pause")]
public static extern void Pause (MediaControlHandle self, IntPtr dummy, ref NativeException e);
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_resume")]
public static extern void Resume (MediaControlHandle self, IntPtr dummy, ref NativeException e);
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_stop")]
public static extern void Stop (MediaControlHandle self, IntPtr dummy, ref NativeException e);
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_playlist_add_item")]
public static extern void PlaylistAddItem (MediaControlHandle self, U8String mrl, ref NativeException e);
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_playlist_clear")]
public static extern void PlaylistClear (MediaControlHandle self, ref NativeException e);
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_playlist_get_list")]
public static extern IntPtr PlaylistGetList (MediaControlHandle self, ref NativeException e);
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_playlist_next_item")]
public static extern void PlaylistNextItem (MediaControlHandle self, ref NativeException e);
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_sound_get_volume")]
public static extern short SoundGetVolume (MediaControlHandle self, ref NativeException e);
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_sound_set_volume")]
public static extern void SoundSetVolume (MediaControlHandle self, short volume, ref NativeException e);
/* SetVisual */
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_get_rate")]
public static extern short GetRate (MediaControlHandle self, ref NativeException e);
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_set_rate")]
public static extern void SetRate (MediaControlHandle self, int rate, ref NativeException e);
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_get_fullscreen")]
public static extern int GetFullscreen (MediaControlHandle self, ref NativeException e);
[DllImport ("libvlc-control.dll", EntryPoint="mediacontrol_set_fullscreen")]
public static extern void SetFullscreen (MediaControlHandle self, int full, ref NativeException e);
};
/**
* Abstract safe handle class for non-NULL pointers
* (Microsoft.* namespace has a similar class, but lets stick to System.*)
......@@ -82,133 +41,7 @@ namespace VideoLAN.VLC
{
get
{
return IsClosed || (handle == IntPtr.Zero);
}
}
};
internal sealed class MediaControlHandle : NonNullHandle
{
private MediaControlHandle ()
{
}
protected override bool ReleaseHandle ()
{
MediaControlAPI.Exit (handle);
return true;
}
};
/**
* Wrapper around native UTF-8 nul-terminated character arrays
*/
[StructLayout (LayoutKind.Sequential)]
internal sealed struct U8String
{
byte[] mb_str;
public U8String (string value)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes (value);
mb_str = new byte[bytes.Length + 1];
Array.Copy (bytes, mb_str, bytes.Length);
mb_str[bytes.Length] = 0;
}
public U8String (IntPtr ptr)
{
if (ptr == IntPtr.Zero)
return;
int i = 0;
while (Marshal.ReadByte (ptr, i) != 0)
i++;
i++;
mb_str = new byte[i];
Marshal.Copy (ptr, mb_str, 0, i);
}
public override string ToString ()
{
if (mb_str == null)
return null;
byte[] bytes = new byte[mb_str.Length - 1];
Array.Copy (mb_str, bytes, bytes.Length);
return System.Text.Encoding.UTF8.GetString (bytes);
}
};
/**
* LibVLC native exception structure
*/
[StructLayout (LayoutKind.Sequential)]
internal sealed struct NativeException
{
public int code;
public IntPtr message;
public string Message
{
get
{
return new U8String (message).ToString ();
}
}
[DllImport ("libvlc-control.dll")]
static extern void mediacontrol_exception_init (ref NativeException e);
[DllImport ("libvlc-control.dll")]
static extern void mediacontrol_exception_cleanup (ref NativeException e);
public static NativeException Prepare ()
{
NativeException e = new NativeException ();
mediacontrol_exception_init (ref e);
return e;
}
public void Consume ()
{
try
{
Exception e;
string m = Message;
switch (this.code)
{
case 0:
e = null;
break;
case 1:
e = new PositionKeyNotSupportedException (m);
break;
case 2:
e = new PositionOriginNotSupportedException (m);
break;
case 3:
e = new InvalidPositionException (m);
break;
case 4:
e = new PlaylistException (m);
break;
case 5:
e = new InternalException (m);
break;
default:
e = new MediaException (m);
break;
}
if (e != null)
throw e;
}
finally
{
mediacontrol_exception_cleanup (ref this);
return handle == IntPtr.Zero;
}
}
};
......
......@@ -22,6 +22,7 @@
**********************************************************************/
using System;
using VideoLAN.LibVLC;
namespace VideoLAN.VLC
{
......@@ -29,25 +30,7 @@ namespace VideoLAN.VLC
{
public static int Main (string[] args)
{
MediaControl mc = new MediaControl (args);
foreach (string s in args)
mc.AddItem (s);
Console.WriteLine ("Volume : {0}%", mc.SoundVolume);
Console.WriteLine ("Rate : {0}%", mc.Rate);
Console.WriteLine ("Fullscreen: {0}", mc.Fullscreen);
mc.Fullscreen = false;
/*mc.Play ();*/
Console.ReadLine ();
mc.Stop ();
mc.Clear ();
mc.SoundVolume = 100;
mc.Rate = 100;
mc.Dispose ();
VLCInstance vlc = new VLCInstance (args);
return 0;
}
};
......
/*
* ustring.cs - Managed LibVLC string
*
* $Id$
*/
/**********************************************************************
* Copyright (C) 2007 Rémi Denis-Courmont. *
* This program is free software; you can redistribute and/or modify *
* it under the terms of the GNU General Public License as published *
* by the Free Software Foundation; version 2 of the license, or (at *
* your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, you can get it from: *
* http://www.gnu.org/copyleft/gpl.html *
**********************************************************************/
using System;
using System.Runtime.InteropServices;
namespace VideoLAN.LibVLC
{
/**
* Managed class for UTF-8 nul-terminated character arrays
*/
[StructLayout (LayoutKind.Sequential)]
public sealed struct U8String
{
public byte[] mb_str;
public U8String (string value)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes (value);
mb_str = new byte[bytes.Length + 1];
Array.Copy (bytes, mb_str, bytes.Length);
mb_str[bytes.Length] = 0;
}
public U8String (IntPtr ptr)
{
if (ptr == IntPtr.Zero)
return;
int i = 0;
while (Marshal.ReadByte (ptr, i) != 0)
i++;
i++;
mb_str = new byte[i];
Marshal.Copy (ptr, mb_str, 0, i);
}
public override string ToString ()
{
if (mb_str == null)
return null;
byte[] bytes = new byte[mb_str.Length - 1];
Array.Copy (mb_str, bytes, bytes.Length);
return System.Text.Encoding.UTF8.GetString (bytes);
}
public static string FromNative (IntPtr ptr)
{
return new U8String (ptr).ToString ();
}
};
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment