diff options
author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2009-04-30 13:10:15 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2009-04-30 13:10:15 +0200 |
commit | d627d1580c159351eaa86a8380c744af05e0477e (patch) | |
tree | e98c0a5a7502d5661d4b159f2eaa72499a410e0a | |
parent | f3e78cd007a253f291da1d08c05bde4b7e64ac42 (diff) |
Fix Gst.TypeFind bindings
-rw-r--r-- | gstreamer-sharp/Gstreamer.metadata | 5 | ||||
-rw-r--r-- | gstreamer-sharp/Makefile.am | 6 | ||||
-rw-r--r-- | gstreamer-sharp/TypeFind.custom | 46 | ||||
-rw-r--r-- | gstreamer-sharp/TypeFindDelegates.cs | 265 | ||||
-rw-r--r-- | gstreamer-sharp/glue/Makefile.am | 3 | ||||
-rw-r--r-- | gstreamer-sharp/glue/typefind.c | 19 |
6 files changed, 340 insertions, 4 deletions
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 @@ | |||
840 | <attr path="/api/namespace/callback[@name='TagMergeFunc']/parameters/parameter[@name='dest']" name="pass_as">out</attr> | 840 | <attr path="/api/namespace/callback[@name='TagMergeFunc']/parameters/parameter[@name='dest']" name="pass_as">out</attr> |
841 | <attr path="/api/namespace/callback[@name='TagMergeFunc']/parameters/parameter[@name='src']" name="pass_as">ref</attr> | 841 | <attr path="/api/namespace/callback[@name='TagMergeFunc']/parameters/parameter[@name='src']" name="pass_as">ref</attr> |
842 | 842 | ||
843 | <attr path="/api/namespace/struct[@name='TypeFind']/method[@name='Register']" name="hidden">1</attr> | 843 | <change-node-type path="/api/namespace/struct[@name='TypeFind']">boxed</change-node-type> |
844 | <attr path="/api/namespace/boxed[@name='TypeFind']" name="opaque">true</attr> | ||
845 | <attr path="/api/namespace/boxed[@name='TypeFind']/method[@cname='gst_type_find_register']" name="hidden">1</attr> | ||
846 | <attr path="/api/namespace/boxed[@name='TypeFind']/method[@cname='gst_type_find_peek']" name="hidden">1</attr> | ||
844 | 847 | ||
845 | <attr path="/api/namespace/object[@name='TypeFindFactory']/method[@cname='gst_type_find_factory_get_list']/return-type" name="element_type">GstTypeFindFactory*</attr> | 848 | <attr path="/api/namespace/object[@name='TypeFindFactory']/method[@cname='gst_type_find_factory_get_list']/return-type" name="element_type">GstTypeFindFactory*</attr> |
846 | <attr path="/api/namespace/object[@name='TypeFindFactory']/method[@cname='gst_type_find_factory_get_list']/return-type" name="elements_owned">true</attr> | 849 | <attr path="/api/namespace/object[@name='TypeFindFactory']/method[@cname='gst_type_find_factory_get_list']/return-type" name="elements_owned">true</attr> |
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 = \ | |||
48 | plugins-base/DecodeBin.cs \ | 48 | plugins-base/DecodeBin.cs \ |
49 | plugins-base/TypeFindElement.cs \ | 49 | plugins-base/TypeFindElement.cs \ |
50 | GstSharp.PadQueryTypeFunctionNative.cs \ | 50 | GstSharp.PadQueryTypeFunctionNative.cs \ |
51 | PadQueryTypeFunction.cs | 51 | PadQueryTypeFunction.cs \ |
52 | TypeFindDelegates.cs | ||
52 | 53 | ||
53 | build_sources = $(addprefix $(srcdir)/, $(sources)) | 54 | build_sources = $(addprefix $(srcdir)/, $(sources)) |
54 | 55 | ||
@@ -74,7 +75,8 @@ customs = \ | |||
74 | Query.custom \ | 75 | Query.custom \ |
75 | Structure.custom \ | 76 | Structure.custom \ |
76 | Tag.custom \ | 77 | Tag.custom \ |
77 | TagList.custom | 78 | TagList.custom \ |
79 | TypeFind.custom | ||
78 | 80 | ||
79 | build_customs = $(addprefix $(srcdir)/, $(customs)) | 81 | build_customs = $(addprefix $(srcdir)/, $(customs)) |
80 | 82 | ||
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 @@ | |||
1 | [DllImport ("gstreamer-0.10.dll") ] | ||
2 | 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); | ||
3 | |||
4 | public static bool Register (Gst.Plugin plugin, string name, uint rank, Gst.TypeFindFunction func, string extensions, Gst.Caps possible_caps) { | ||
5 | IntPtr native_name = GLib.Marshaller.StringToPtrGStrdup (name); | ||
6 | GstSharp.TypeFindFunctionWrapper func_wrapper = new GstSharp.TypeFindFunctionWrapper (func); | ||
7 | 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); | ||
8 | bool ret = raw_ret; | ||
9 | GLib.Marshaller.Free (native_name); | ||
10 | return ret; | ||
11 | } | ||
12 | |||
13 | [DllImport ("gstreamer-0.10.dll") ] | ||
14 | static extern IntPtr gst_type_find_peek (IntPtr raw, long offset, uint size); | ||
15 | |||
16 | public byte[] Peek (long offset, uint size) { | ||
17 | IntPtr raw_ret = gst_type_find_peek (Handle, offset, size); | ||
18 | if (raw_ret == IntPtr.Zero) | ||
19 | return null; | ||
20 | |||
21 | byte[] ret = new byte[size]; | ||
22 | Marshal.Copy (raw_ret, ret, 0, (int) size); | ||
23 | return ret; | ||
24 | } | ||
25 | |||
26 | private GstSharp.TypeFindPeekFunctionWrapper peek; | ||
27 | private GstSharp.TypeFindSuggestFunctionWrapper suggest; | ||
28 | private GstSharp.TypeFindGetLengthFunctionWrapper get_length; | ||
29 | |||
30 | [DllImport ("gstreamersharpglue-0.10") ] | ||
31 | static extern IntPtr gstsharp_gst_type_find_new (GstSharp.TypeFindPeekFunctionNative peek, GstSharp.TypeFindSuggestFunctionNative suggest, GstSharp.TypeFindGetLengthFunctionNative get_length); | ||
32 | |||
33 | |||
34 | |||
35 | public TypeFind (TypeFindPeekFunction peek, TypeFindSuggestFunction suggest, TypeFindGetLengthFunction get_length) : base () { | ||
36 | this.peek = new GstSharp.TypeFindPeekFunctionWrapper (peek); | ||
37 | this.suggest = new GstSharp.TypeFindSuggestFunctionWrapper (suggest); | ||
38 | this.get_length = new GstSharp.TypeFindGetLengthFunctionWrapper (get_length); | ||
39 | |||
40 | Raw = gstsharp_gst_type_find_new (this.peek.NativeDelegate, this.suggest.NativeDelegate, this.get_length.NativeDelegate); | ||
41 | Owned = true; | ||
42 | } | ||
43 | |||
44 | protected override void Free (IntPtr raw) { | ||
45 | GLib.Marshaller.Free (raw); | ||
46 | } | ||
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 @@ | |||
1 | using System; | ||
2 | using System.Runtime.InteropServices; | ||
3 | using System.Collections; | ||
4 | |||
5 | namespace Gst { | ||
6 | public delegate byte[] TypeFindPeekFunction (long offset, uint size); | ||
7 | public delegate void TypeFindSuggestFunction (uint propability, Gst.Caps caps); | ||
8 | public delegate ulong TypeFindGetLengthFunction (); | ||
9 | } | ||
10 | |||
11 | namespace GstSharp { | ||
12 | |||
13 | [GLib.CDeclCallback] | ||
14 | internal delegate IntPtr TypeFindPeekFunctionNative (IntPtr data, long offset, uint size); | ||
15 | |||
16 | internal class TypeFindPeekFunctionInvoker { | ||
17 | |||
18 | TypeFindPeekFunctionNative native_cb; | ||
19 | IntPtr __data; | ||
20 | GLib.DestroyNotify __notify; | ||
21 | |||
22 | ~TypeFindPeekFunctionInvoker () { | ||
23 | if (__notify == null) | ||
24 | return; | ||
25 | __notify (__data); | ||
26 | } | ||
27 | |||
28 | internal TypeFindPeekFunctionInvoker (TypeFindPeekFunctionNative native_cb) : this (native_cb, IntPtr.Zero, null) {} | ||
29 | |||
30 | internal TypeFindPeekFunctionInvoker (TypeFindPeekFunctionNative native_cb, IntPtr data) : this (native_cb, data, null) {} | ||
31 | |||
32 | internal TypeFindPeekFunctionInvoker (TypeFindPeekFunctionNative native_cb, IntPtr data, GLib.DestroyNotify notify) { | ||
33 | this.native_cb = native_cb; | ||
34 | __data = data; | ||
35 | __notify = notify; | ||
36 | } | ||
37 | |||
38 | internal Gst.TypeFindPeekFunction Handler { | ||
39 | get { | ||
40 | return new Gst.TypeFindPeekFunction (InvokeNative); | ||
41 | } | ||
42 | } | ||
43 | |||
44 | byte[] InvokeNative (long offset, uint size) { | ||
45 | IntPtr raw_ret = native_cb (IntPtr.Zero, offset, size); | ||
46 | if (raw_ret == IntPtr.Zero) | ||
47 | return new byte[] {}; | ||
48 | |||
49 | byte[] ret = new byte[size]; | ||
50 | Marshal.Copy (raw_ret, ret, 0, (int) size); | ||
51 | |||
52 | return ret; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | internal class TypeFindPeekFunctionWrapper { | ||
57 | /* FIXME: We should do something more intelligent here */ | ||
58 | private ArrayList data_cache = new ArrayList (); | ||
59 | |||
60 | public IntPtr NativeCallback (IntPtr data, long offset, uint size) { | ||
61 | try { | ||
62 | byte[] __ret = managed (offset, size); | ||
63 | if (release_on_call) | ||
64 | gch.Free (); | ||
65 | if (__ret.Length == 0) | ||
66 | return IntPtr.Zero; | ||
67 | |||
68 | IntPtr raw_ret = Marshal.AllocHGlobal (__ret.Length); | ||
69 | Marshal.Copy (__ret, 0, raw_ret, (int) size); | ||
70 | data_cache.Add (raw_ret); | ||
71 | return raw_ret; | ||
72 | } catch (Exception e) { | ||
73 | GLib.ExceptionManager.RaiseUnhandledException (e, true); | ||
74 | // NOTREACHED: Above call does not return. | ||
75 | throw e; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | ~TypeFindPeekFunctionWrapper() { | ||
80 | foreach (IntPtr raw in data_cache) | ||
81 | Marshal.FreeHGlobal (raw); | ||
82 | data_cache = null; | ||
83 | } | ||
84 | |||
85 | bool release_on_call = false; | ||
86 | GCHandle gch; | ||
87 | |||
88 | public void PersistUntilCalled () { | ||
89 | release_on_call = true; | ||
90 | gch = GCHandle.Alloc (this); | ||
91 | } | ||
92 | |||
93 | internal TypeFindPeekFunctionNative NativeDelegate; | ||
94 | Gst.TypeFindPeekFunction managed; | ||
95 | |||
96 | public TypeFindPeekFunctionWrapper (Gst.TypeFindPeekFunction managed) { | ||
97 | this.managed = managed; | ||
98 | if (managed != null) | ||
99 | NativeDelegate = new TypeFindPeekFunctionNative (NativeCallback); | ||
100 | } | ||
101 | |||
102 | public static Gst.TypeFindPeekFunction GetManagedDelegate (TypeFindPeekFunctionNative native) { | ||
103 | if (native == null) | ||
104 | return null; | ||
105 | TypeFindPeekFunctionWrapper wrapper = (TypeFindPeekFunctionWrapper) native.Target; | ||
106 | if (wrapper == null) | ||
107 | return null; | ||
108 | return wrapper.managed; | ||
109 | } | ||
110 | } | ||
111 | |||
112 | [GLib.CDeclCallback] | ||
113 | internal delegate void TypeFindSuggestFunctionNative (IntPtr data, uint propability, IntPtr caps); | ||
114 | |||
115 | internal class TypeFindSuggestFunctionInvoker { | ||
116 | |||
117 | TypeFindSuggestFunctionNative native_cb; | ||
118 | IntPtr __data; | ||
119 | GLib.DestroyNotify __notify; | ||
120 | |||
121 | ~TypeFindSuggestFunctionInvoker () { | ||
122 | if (__notify == null) | ||
123 | return; | ||
124 | __notify (__data); | ||
125 | } | ||
126 | |||
127 | internal TypeFindSuggestFunctionInvoker (TypeFindSuggestFunctionNative native_cb) : this (native_cb, IntPtr.Zero, null) {} | ||
128 | |||
129 | internal TypeFindSuggestFunctionInvoker (TypeFindSuggestFunctionNative native_cb, IntPtr data) : this (native_cb, data, null) {} | ||
130 | |||
131 | internal TypeFindSuggestFunctionInvoker (TypeFindSuggestFunctionNative native_cb, IntPtr data, GLib.DestroyNotify notify) { | ||
132 | this.native_cb = native_cb; | ||
133 | __data = data; | ||
134 | __notify = notify; | ||
135 | } | ||
136 | |||
137 | internal Gst.TypeFindSuggestFunction Handler { | ||
138 | get { | ||
139 | return new Gst.TypeFindSuggestFunction (InvokeNative); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | void InvokeNative (uint propability, Gst.Caps caps) { | ||
144 | native_cb (IntPtr.Zero, propability, caps.Handle); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | internal class TypeFindSuggestFunctionWrapper { | ||
149 | public void NativeCallback (IntPtr data, uint propability, IntPtr caps) { | ||
150 | try { | ||
151 | managed (propability, (Gst.Caps) GLib.Opaque.GetOpaque (caps, typeof (Gst.Caps), false)); | ||
152 | if (release_on_call) | ||
153 | gch.Free (); | ||
154 | } catch (Exception e) { | ||
155 | GLib.ExceptionManager.RaiseUnhandledException (e, true); | ||
156 | // NOTREACHED: Above call does not return. | ||
157 | throw e; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | bool release_on_call = false; | ||
162 | GCHandle gch; | ||
163 | |||
164 | public void PersistUntilCalled () { | ||
165 | release_on_call = true; | ||
166 | gch = GCHandle.Alloc (this); | ||
167 | } | ||
168 | |||
169 | internal TypeFindSuggestFunctionNative NativeDelegate; | ||
170 | Gst.TypeFindSuggestFunction managed; | ||
171 | |||
172 | public TypeFindSuggestFunctionWrapper (Gst.TypeFindSuggestFunction managed) { | ||
173 | this.managed = managed; | ||
174 | if (managed != null) | ||
175 | NativeDelegate = new TypeFindSuggestFunctionNative (NativeCallback); | ||
176 | } | ||
177 | |||
178 | public static Gst.TypeFindSuggestFunction GetManagedDelegate (TypeFindSuggestFunctionNative native) { | ||
179 | if (native == null) | ||
180 | return null; | ||
181 | TypeFindSuggestFunctionWrapper wrapper = (TypeFindSuggestFunctionWrapper) native.Target; | ||
182 | if (wrapper == null) | ||
183 | return null; | ||
184 | return wrapper.managed; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | [GLib.CDeclCallback] | ||
189 | internal delegate ulong TypeFindGetLengthFunctionNative (IntPtr data); | ||
190 | |||
191 | internal class TypeFindGetLengthFunctionInvoker { | ||
192 | |||
193 | TypeFindGetLengthFunctionNative native_cb; | ||
194 | IntPtr __data; | ||
195 | GLib.DestroyNotify __notify; | ||
196 | |||
197 | ~TypeFindGetLengthFunctionInvoker () { | ||
198 | if (__notify == null) | ||
199 | return; | ||
200 | __notify (__data); | ||
201 | } | ||
202 | |||
203 | internal TypeFindGetLengthFunctionInvoker (TypeFindGetLengthFunctionNative native_cb) : this (native_cb, IntPtr.Zero, null) {} | ||
204 | |||
205 | internal TypeFindGetLengthFunctionInvoker (TypeFindGetLengthFunctionNative native_cb, IntPtr data) : this (native_cb, data, null) {} | ||
206 | |||
207 | internal TypeFindGetLengthFunctionInvoker (TypeFindGetLengthFunctionNative native_cb, IntPtr data, GLib.DestroyNotify notify) { | ||
208 | this.native_cb = native_cb; | ||
209 | __data = data; | ||
210 | __notify = notify; | ||
211 | } | ||
212 | |||
213 | internal Gst.TypeFindGetLengthFunction Handler { | ||
214 | get { | ||
215 | return new Gst.TypeFindGetLengthFunction (InvokeNative); | ||
216 | } | ||
217 | } | ||
218 | |||
219 | ulong InvokeNative () { | ||
220 | ulong ret = native_cb (IntPtr.Zero); | ||
221 | return ret; | ||
222 | } | ||
223 | } | ||
224 | |||
225 | internal class TypeFindGetLengthFunctionWrapper { | ||
226 | public ulong NativeCallback (IntPtr data) { | ||
227 | try { | ||
228 | ulong ret = managed (); | ||
229 | if (release_on_call) | ||
230 | gch.Free (); | ||
231 | return ret; | ||
232 | } catch (Exception e) { | ||
233 | GLib.ExceptionManager.RaiseUnhandledException (e, true); | ||
234 | // NOTREACHED: Above call does not return. | ||
235 | throw e; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | bool release_on_call = false; | ||
240 | GCHandle gch; | ||
241 | |||
242 | public void PersistUntilCalled () { | ||
243 | release_on_call = true; | ||
244 | gch = GCHandle.Alloc (this); | ||
245 | } | ||
246 | |||
247 | internal TypeFindGetLengthFunctionNative NativeDelegate; | ||
248 | Gst.TypeFindGetLengthFunction managed; | ||
249 | |||
250 | public TypeFindGetLengthFunctionWrapper (Gst.TypeFindGetLengthFunction managed) { | ||
251 | this.managed = managed; | ||
252 | if (managed != null) | ||
253 | NativeDelegate = new TypeFindGetLengthFunctionNative (NativeCallback); | ||
254 | } | ||
255 | |||
256 | public static Gst.TypeFindGetLengthFunction GetManagedDelegate (TypeFindGetLengthFunctionNative native) { | ||
257 | if (native == null) | ||
258 | return null; | ||
259 | TypeFindGetLengthFunctionWrapper wrapper = (TypeFindGetLengthFunctionWrapper) native.Target; | ||
260 | if (wrapper == null) | ||
261 | return null; | ||
262 | return wrapper.managed; | ||
263 | } | ||
264 | } | ||
265 | } | ||
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 = \ | |||
13 | task.c \ | 13 | task.c \ |
14 | object.c \ | 14 | object.c \ |
15 | pad.c \ | 15 | pad.c \ |
16 | gobject.c | 16 | gobject.c \ |
17 | typefind.c | ||
17 | 18 | ||
18 | nodist_libgstreamersharpglue_0_10_la_SOURCES = generated.c | 19 | nodist_libgstreamersharpglue_0_10_la_SOURCES = generated.c |
19 | 20 | ||
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 @@ | |||
1 | #include <gst/gst.h> | ||
2 | |||
3 | typedef guint8 *(*PeekFunction) (gpointer data, gint64 offset, guint size); | ||
4 | typedef void (*SuggestFunction) (gpointer data, guint probabilty, | ||
5 | GstCaps * caps); | ||
6 | typedef guint64 (*GetLengthFunction) (gpointer data); | ||
7 | |||
8 | GstTypeFind * | ||
9 | gstsharp_gst_type_find_new (PeekFunction peek, SuggestFunction suggest, | ||
10 | GetLengthFunction get_length) | ||
11 | { | ||
12 | GstTypeFind *ret = g_new0 (GstTypeFind, 1); | ||
13 | |||
14 | ret->peek = peek; | ||
15 | ret->suggest = suggest; | ||
16 | ret->get_length = get_length; | ||
17 | |||
18 | return ret; | ||
19 | } | ||