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 = CSFLAGS =
TARGETS = VideoLAN.VLC.Control.dll testvlc.exe TARGETS = VideoLAN.VLC.Control.dll testvlc.exe
...@@ -6,9 +6,9 @@ TARGETS = VideoLAN.VLC.Control.dll testvlc.exe ...@@ -6,9 +6,9 @@ TARGETS = VideoLAN.VLC.Control.dll testvlc.exe
all: $(TARGETS) all: $(TARGETS)
clean: 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 testvlc.exe: testvlc.cs VideoLAN.VLC.Control.dll
%.netmodule: %.cs Makefile %.netmodule: %.cs Makefile
......
...@@ -22,111 +22,73 @@ ...@@ -22,111 +22,73 @@
**********************************************************************/ **********************************************************************/
using System; 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) : base (message)
{ {
} }
public MediaException (string message, Exception inner) public VLCException (string message, Exception inner)
: base (message, inner) : base (message, inner)
{ {
} }
}; };
public class PositionKeyNotSupportedException : MediaException /**
{ * libvlc_exception_t: structure for unmanaged LibVLC exceptions
public PositionKeyNotSupportedException () */
{ [StructLayout (LayoutKind.Sequential)]
} internal sealed class NativeException : IDisposable
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
{ {
public PlaylistException () int raised;
{ int code;
} IntPtr message;
public PlaylistException (string message) [DllImport ("libvlc-control.dll", EntryPoint="libvlc_exception_init")]
: base (message) 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) public NativeException ()
: base (message, inner)
{ {
Init (this);
} }
};
public class InternalException : MediaException public void Raise ()
{
public InternalException ()
{
}
public InternalException (string message)
: base (message)
{ {
try
{
string msg = U8String.FromNative (GetMessage (this));
if (msg != null)
throw new VLCException (msg);
}
finally
{
Clear (this);
}
} }
public InternalException (string message, Exception inner) public void Dispose ()
: base (message, inner)
{ {
Clear (this);
} }
}; };
}; };
...@@ -24,225 +24,94 @@ ...@@ -24,225 +24,94 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace VideoLAN.VLC namespace VideoLAN.LibVLC
{ {
/** Safe handle for unmanaged LibVLC instance pointer */
public class MediaControl : IDisposable internal sealed class InstanceHandle : NonNullHandle
{ {
/** private InstanceHandle ()
* Possible player status
*/
enum PlayerStatus
{
PlayingStatus,
PauseStatus,
ForwardStatus,
BackwardStatus,
InitStatus,
EndStatus,
UndefinedStatus,
};
enum PositionOrigin
{ {
AbsolutePosition, }
RelativePosition,
ModuloPosition,
};
enum PositionKey [DllImport ("libvlc-control.dll", EntryPoint="libvlc_new")]
{ public static extern
ByteCount, InstanceHandle Create (int argc, U8String[] argv, NativeException ex);
SampleCount,
MediaTime,
};
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) Destroy (this, null);
throw new ObjectDisposedException ("Media controlled disposed"); return true;
} }
};
/** public class VLCInstance : IDisposable
* Creates a MediaControl with a new LibVLC instance {
*/ NativeException ex;
public MediaControl (string[] args) InstanceHandle self;
{
NativeException e = NativeException.Prepare ();
public VLCInstance (string[] args)
{
U8String[] argv = new U8String[args.Length]; U8String[] argv = new U8String[args.Length];
for (int i = 0; i < args.Length; i++) for (int i = 0; i < args.Length; i++)
argv[i] = new U8String (args[i]); argv[i] = new U8String (args[i]);
self = MediaControlAPI.New (argv.Length, argv, ref e); ex = new NativeException ();
e.Consume (); self = InstanceHandle.Create (argv.Length, argv, ex);
} ex.Raise ();
/**
* 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 ();
} }
public void Pause () public void Dispose ()
{
CheckDisposed ();
NativeException e = NativeException.Prepare ();
MediaControlAPI.Pause (self, IntPtr.Zero, ref e);
e.Consume ();
}
public void Stop ()
{ {
CheckDisposed (); ex.Dispose ();
self.Close ();
NativeException e = NativeException.Prepare ();
MediaControlAPI.Stop (self, IntPtr.Zero, ref e);
e.Consume ();
} }
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); return new MediaDescriptor (dh);
NativeException e = NativeException.Prepare ();
MediaControlAPI.PlaylistAddItem (self, nmrl, ref e);
e.Consume ();
} }
};
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 [DllImport ("libvlc-control.dll",
{ EntryPoint="libvlc_media_descriptor_new")]
get public static extern
{ DescriptorHandle Create (InstanceHandle inst, U8String mrl,
CheckDisposed (); NativeException ex);
throw new NotImplementedException ();
}
}
/** [DllImport ("libvlc-control.dll",
* Switches to the next playlist item EntryPoint="libvlc_media_descriptor_release")]
*/ public static extern void Release (DescriptorHandle ptr);
public void NextItem ()
{
CheckDisposed ();
NativeException e = NativeException.Prepare (); protected override bool ReleaseHandle ()
MediaControlAPI.PlaylistNextItem (self, ref e);
e.Consume ();
}
/**
* Normalized audio output volume in percent (must be [0..100]).
*/
public short SoundVolume
{ {
get Release (this);
{ return true;
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 ();
}
} }
};
/** public class MediaDescriptor
* Fullscreen flag. {
*/ NativeException ex;
public bool Fullscreen DescriptorHandle self;
{
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 void Dispose () internal MediaDescriptor (DescriptorHandle self)
{ {
self.Dispose (); this.self = self;
ex = new NativeException ();
} }
}; };
}; };
...@@ -24,49 +24,8 @@ ...@@ -24,49 +24,8 @@
using System; using System;
using System.Runtime.InteropServices; 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 * Abstract safe handle class for non-NULL pointers
* (Microsoft.* namespace has a similar class, but lets stick to System.*) * (Microsoft.* namespace has a similar class, but lets stick to System.*)
...@@ -82,133 +41,7 @@ namespace VideoLAN.VLC ...@@ -82,133 +41,7 @@ namespace VideoLAN.VLC
{ {
get get
{ {
return IsClosed || (handle == IntPtr.Zero); return 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);
} }
} }
}; };
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
**********************************************************************/ **********************************************************************/
using System; using System;
using VideoLAN.LibVLC;
namespace VideoLAN.VLC namespace VideoLAN.VLC
{ {
...@@ -29,25 +30,7 @@ namespace VideoLAN.VLC ...@@ -29,25 +30,7 @@ namespace VideoLAN.VLC
{ {
public static int Main (string[] args) public static int Main (string[] args)
{ {
MediaControl mc = new MediaControl (args); VLCInstance vlc = new VLCInstance (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 ();
return 0; 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