From d627d1580c159351eaa86a8380c744af05e0477e Mon Sep 17 00:00:00 2001 From: Sebastian Dröge Date: Thu, 30 Apr 2009 13:10:15 +0200 Subject: Fix Gst.TypeFind bindings --- gstreamer-sharp/Gstreamer.metadata | 5 +- gstreamer-sharp/Makefile.am | 6 +- gstreamer-sharp/TypeFind.custom | 46 ++++++ gstreamer-sharp/TypeFindDelegates.cs | 265 +++++++++++++++++++++++++++++++++++ gstreamer-sharp/glue/Makefile.am | 3 +- gstreamer-sharp/glue/typefind.c | 19 +++ 6 files changed, 340 insertions(+), 4 deletions(-) create mode 100644 gstreamer-sharp/TypeFind.custom create mode 100644 gstreamer-sharp/TypeFindDelegates.cs create mode 100644 gstreamer-sharp/glue/typefind.c diff --git a/gstreamer-sharp/Gstreamer.metadata b/gstreamer-sharp/Gstreamer.metadata index 9ccfec7..987283b 100644 --- a/gstreamer-sharp/Gstreamer.metadata +++ b/gstreamer-sharp/Gstreamer.metadata @@ -840,7 +840,10 @@ out ref - 1 + boxed + true + 1 + 1 GstTypeFindFactory* true diff --git a/gstreamer-sharp/Makefile.am b/gstreamer-sharp/Makefile.am index bb16e09..4307a0e 100644 --- a/gstreamer-sharp/Makefile.am +++ b/gstreamer-sharp/Makefile.am @@ -48,7 +48,8 @@ sources = \ plugins-base/DecodeBin.cs \ plugins-base/TypeFindElement.cs \ GstSharp.PadQueryTypeFunctionNative.cs \ - PadQueryTypeFunction.cs + PadQueryTypeFunction.cs \ + TypeFindDelegates.cs build_sources = $(addprefix $(srcdir)/, $(sources)) @@ -74,7 +75,8 @@ customs = \ Query.custom \ Structure.custom \ Tag.custom \ - TagList.custom + TagList.custom \ + TypeFind.custom build_customs = $(addprefix $(srcdir)/, $(customs)) diff --git a/gstreamer-sharp/TypeFind.custom b/gstreamer-sharp/TypeFind.custom new file mode 100644 index 0000000..70d99fe --- /dev/null +++ b/gstreamer-sharp/TypeFind.custom @@ -0,0 +1,46 @@ +[DllImport ("gstreamer-0.10.dll") ] +static extern bool gst_type_find_register (IntPtr plugin, IntPtr name, uint rank, GstSharp.TypeFindFunctionNative func, IntPtr extensions, IntPtr possible_caps, IntPtr data, IntPtr data_notify); + +public static bool Register (Gst.Plugin plugin, string name, uint rank, Gst.TypeFindFunction func, string extensions, Gst.Caps possible_caps) { + IntPtr native_name = GLib.Marshaller.StringToPtrGStrdup (name); + GstSharp.TypeFindFunctionWrapper func_wrapper = new GstSharp.TypeFindFunctionWrapper (func); + bool raw_ret = gst_type_find_register (plugin == null ? IntPtr.Zero : plugin.Handle, native_name, rank, func_wrapper.NativeDelegate, GLib.Marshaller.StringToPtrGStrdup (extensions), possible_caps == null ? IntPtr.Zero : possible_caps.Handle, IntPtr.Zero, IntPtr.Zero); + bool ret = raw_ret; + GLib.Marshaller.Free (native_name); + return ret; +} + +[DllImport ("gstreamer-0.10.dll") ] +static extern IntPtr gst_type_find_peek (IntPtr raw, long offset, uint size); + +public byte[] Peek (long offset, uint size) { + IntPtr raw_ret = gst_type_find_peek (Handle, offset, size); + if (raw_ret == IntPtr.Zero) + return null; + + byte[] ret = new byte[size]; + Marshal.Copy (raw_ret, ret, 0, (int) size); + return ret; +} + +private GstSharp.TypeFindPeekFunctionWrapper peek; +private GstSharp.TypeFindSuggestFunctionWrapper suggest; +private GstSharp.TypeFindGetLengthFunctionWrapper get_length; + +[DllImport ("gstreamersharpglue-0.10") ] +static extern IntPtr gstsharp_gst_type_find_new (GstSharp.TypeFindPeekFunctionNative peek, GstSharp.TypeFindSuggestFunctionNative suggest, GstSharp.TypeFindGetLengthFunctionNative get_length); + + + +public TypeFind (TypeFindPeekFunction peek, TypeFindSuggestFunction suggest, TypeFindGetLengthFunction get_length) : base () { + this.peek = new GstSharp.TypeFindPeekFunctionWrapper (peek); + this.suggest = new GstSharp.TypeFindSuggestFunctionWrapper (suggest); + this.get_length = new GstSharp.TypeFindGetLengthFunctionWrapper (get_length); + + Raw = gstsharp_gst_type_find_new (this.peek.NativeDelegate, this.suggest.NativeDelegate, this.get_length.NativeDelegate); + Owned = true; +} + +protected override void Free (IntPtr raw) { + GLib.Marshaller.Free (raw); +} diff --git a/gstreamer-sharp/TypeFindDelegates.cs b/gstreamer-sharp/TypeFindDelegates.cs new file mode 100644 index 0000000..8125ae6 --- /dev/null +++ b/gstreamer-sharp/TypeFindDelegates.cs @@ -0,0 +1,265 @@ +using System; +using System.Runtime.InteropServices; +using System.Collections; + +namespace Gst { + public delegate byte[] TypeFindPeekFunction (long offset, uint size); + public delegate void TypeFindSuggestFunction (uint propability, Gst.Caps caps); + public delegate ulong TypeFindGetLengthFunction (); +} + +namespace GstSharp { + + [GLib.CDeclCallback] + internal delegate IntPtr TypeFindPeekFunctionNative (IntPtr data, long offset, uint size); + + internal class TypeFindPeekFunctionInvoker { + + TypeFindPeekFunctionNative native_cb; + IntPtr __data; + GLib.DestroyNotify __notify; + + ~TypeFindPeekFunctionInvoker () { + if (__notify == null) + return; + __notify (__data); + } + + internal TypeFindPeekFunctionInvoker (TypeFindPeekFunctionNative native_cb) : this (native_cb, IntPtr.Zero, null) {} + + internal TypeFindPeekFunctionInvoker (TypeFindPeekFunctionNative native_cb, IntPtr data) : this (native_cb, data, null) {} + + internal TypeFindPeekFunctionInvoker (TypeFindPeekFunctionNative native_cb, IntPtr data, GLib.DestroyNotify notify) { + this.native_cb = native_cb; + __data = data; + __notify = notify; + } + + internal Gst.TypeFindPeekFunction Handler { + get { + return new Gst.TypeFindPeekFunction (InvokeNative); + } + } + + byte[] InvokeNative (long offset, uint size) { + IntPtr raw_ret = native_cb (IntPtr.Zero, offset, size); + if (raw_ret == IntPtr.Zero) + return new byte[] {}; + + byte[] ret = new byte[size]; + Marshal.Copy (raw_ret, ret, 0, (int) size); + + return ret; + } + } + + internal class TypeFindPeekFunctionWrapper { + /* FIXME: We should do something more intelligent here */ + private ArrayList data_cache = new ArrayList (); + + public IntPtr NativeCallback (IntPtr data, long offset, uint size) { + try { + byte[] __ret = managed (offset, size); + if (release_on_call) + gch.Free (); + if (__ret.Length == 0) + return IntPtr.Zero; + + IntPtr raw_ret = Marshal.AllocHGlobal (__ret.Length); + Marshal.Copy (__ret, 0, raw_ret, (int) size); + data_cache.Add (raw_ret); + return raw_ret; + } catch (Exception e) { + GLib.ExceptionManager.RaiseUnhandledException (e, true); + // NOTREACHED: Above call does not return. + throw e; + } + } + + ~TypeFindPeekFunctionWrapper() { + foreach (IntPtr raw in data_cache) + Marshal.FreeHGlobal (raw); + data_cache = null; + } + + bool release_on_call = false; + GCHandle gch; + + public void PersistUntilCalled () { + release_on_call = true; + gch = GCHandle.Alloc (this); + } + + internal TypeFindPeekFunctionNative NativeDelegate; + Gst.TypeFindPeekFunction managed; + + public TypeFindPeekFunctionWrapper (Gst.TypeFindPeekFunction managed) { + this.managed = managed; + if (managed != null) + NativeDelegate = new TypeFindPeekFunctionNative (NativeCallback); + } + + public static Gst.TypeFindPeekFunction GetManagedDelegate (TypeFindPeekFunctionNative native) { + if (native == null) + return null; + TypeFindPeekFunctionWrapper wrapper = (TypeFindPeekFunctionWrapper) native.Target; + if (wrapper == null) + return null; + return wrapper.managed; + } + } + + [GLib.CDeclCallback] + internal delegate void TypeFindSuggestFunctionNative (IntPtr data, uint propability, IntPtr caps); + + internal class TypeFindSuggestFunctionInvoker { + + TypeFindSuggestFunctionNative native_cb; + IntPtr __data; + GLib.DestroyNotify __notify; + + ~TypeFindSuggestFunctionInvoker () { + if (__notify == null) + return; + __notify (__data); + } + + internal TypeFindSuggestFunctionInvoker (TypeFindSuggestFunctionNative native_cb) : this (native_cb, IntPtr.Zero, null) {} + + internal TypeFindSuggestFunctionInvoker (TypeFindSuggestFunctionNative native_cb, IntPtr data) : this (native_cb, data, null) {} + + internal TypeFindSuggestFunctionInvoker (TypeFindSuggestFunctionNative native_cb, IntPtr data, GLib.DestroyNotify notify) { + this.native_cb = native_cb; + __data = data; + __notify = notify; + } + + internal Gst.TypeFindSuggestFunction Handler { + get { + return new Gst.TypeFindSuggestFunction (InvokeNative); + } + } + + void InvokeNative (uint propability, Gst.Caps caps) { + native_cb (IntPtr.Zero, propability, caps.Handle); + } + } + + internal class TypeFindSuggestFunctionWrapper { + public void NativeCallback (IntPtr data, uint propability, IntPtr caps) { + try { + managed (propability, (Gst.Caps) GLib.Opaque.GetOpaque (caps, typeof (Gst.Caps), false)); + if (release_on_call) + gch.Free (); + } catch (Exception e) { + GLib.ExceptionManager.RaiseUnhandledException (e, true); + // NOTREACHED: Above call does not return. + throw e; + } + } + + bool release_on_call = false; + GCHandle gch; + + public void PersistUntilCalled () { + release_on_call = true; + gch = GCHandle.Alloc (this); + } + + internal TypeFindSuggestFunctionNative NativeDelegate; + Gst.TypeFindSuggestFunction managed; + + public TypeFindSuggestFunctionWrapper (Gst.TypeFindSuggestFunction managed) { + this.managed = managed; + if (managed != null) + NativeDelegate = new TypeFindSuggestFunctionNative (NativeCallback); + } + + public static Gst.TypeFindSuggestFunction GetManagedDelegate (TypeFindSuggestFunctionNative native) { + if (native == null) + return null; + TypeFindSuggestFunctionWrapper wrapper = (TypeFindSuggestFunctionWrapper) native.Target; + if (wrapper == null) + return null; + return wrapper.managed; + } + } + + [GLib.CDeclCallback] + internal delegate ulong TypeFindGetLengthFunctionNative (IntPtr data); + + internal class TypeFindGetLengthFunctionInvoker { + + TypeFindGetLengthFunctionNative native_cb; + IntPtr __data; + GLib.DestroyNotify __notify; + + ~TypeFindGetLengthFunctionInvoker () { + if (__notify == null) + return; + __notify (__data); + } + + internal TypeFindGetLengthFunctionInvoker (TypeFindGetLengthFunctionNative native_cb) : this (native_cb, IntPtr.Zero, null) {} + + internal TypeFindGetLengthFunctionInvoker (TypeFindGetLengthFunctionNative native_cb, IntPtr data) : this (native_cb, data, null) {} + + internal TypeFindGetLengthFunctionInvoker (TypeFindGetLengthFunctionNative native_cb, IntPtr data, GLib.DestroyNotify notify) { + this.native_cb = native_cb; + __data = data; + __notify = notify; + } + + internal Gst.TypeFindGetLengthFunction Handler { + get { + return new Gst.TypeFindGetLengthFunction (InvokeNative); + } + } + + ulong InvokeNative () { + ulong ret = native_cb (IntPtr.Zero); + return ret; + } + } + + internal class TypeFindGetLengthFunctionWrapper { + public ulong NativeCallback (IntPtr data) { + try { + ulong ret = managed (); + if (release_on_call) + gch.Free (); + return ret; + } catch (Exception e) { + GLib.ExceptionManager.RaiseUnhandledException (e, true); + // NOTREACHED: Above call does not return. + throw e; + } + } + + bool release_on_call = false; + GCHandle gch; + + public void PersistUntilCalled () { + release_on_call = true; + gch = GCHandle.Alloc (this); + } + + internal TypeFindGetLengthFunctionNative NativeDelegate; + Gst.TypeFindGetLengthFunction managed; + + public TypeFindGetLengthFunctionWrapper (Gst.TypeFindGetLengthFunction managed) { + this.managed = managed; + if (managed != null) + NativeDelegate = new TypeFindGetLengthFunctionNative (NativeCallback); + } + + public static Gst.TypeFindGetLengthFunction GetManagedDelegate (TypeFindGetLengthFunctionNative native) { + if (native == null) + return null; + TypeFindGetLengthFunctionWrapper wrapper = (TypeFindGetLengthFunctionWrapper) native.Target; + if (wrapper == null) + return null; + return wrapper.managed; + } + } +} diff --git a/gstreamer-sharp/glue/Makefile.am b/gstreamer-sharp/glue/Makefile.am index 7fb63f0..f5779d9 100644 --- a/gstreamer-sharp/glue/Makefile.am +++ b/gstreamer-sharp/glue/Makefile.am @@ -13,7 +13,8 @@ libgstreamersharpglue_0_10_la_SOURCES = \ task.c \ object.c \ pad.c \ - gobject.c + gobject.c \ + typefind.c nodist_libgstreamersharpglue_0_10_la_SOURCES = generated.c diff --git a/gstreamer-sharp/glue/typefind.c b/gstreamer-sharp/glue/typefind.c new file mode 100644 index 0000000..c7f281d --- /dev/null +++ b/gstreamer-sharp/glue/typefind.c @@ -0,0 +1,19 @@ +#include + +typedef guint8 *(*PeekFunction) (gpointer data, gint64 offset, guint size); +typedef void (*SuggestFunction) (gpointer data, guint probabilty, + GstCaps * caps); +typedef guint64 (*GetLengthFunction) (gpointer data); + +GstTypeFind * +gstsharp_gst_type_find_new (PeekFunction peek, SuggestFunction suggest, + GetLengthFunction get_length) +{ + GstTypeFind *ret = g_new0 (GstTypeFind, 1); + + ret->peek = peek; + ret->suggest = suggest; + ret->get_length = get_length; + + return ret; +} -- cgit v1.2.3