if (IsWritable)
return;
+ RemoveStructureReferences ();
IntPtr copy = gst_caps_copy (Raw);
Raw = copy;
/* ^--- Takes a second ref, not good */
Owned = true;
}
+private Hashtable structures = new Hashtable ();
+
+private void RemoveStructureReference (Structure s) {
+ structures.Remove (s.Handle);
+ s.CreateNativeCopy ();
+}
+
+private void RemoveStructureReferences () {
+ foreach (Structure s in structures.Values) {
+ RemoveStructureReference (s);
+ }
+}
+
[DllImport ("gstreamer-0.10.dll") ]
private static extern IntPtr gst_caps_get_structure (IntPtr handle, uint index);
IntPtr raw_ptr = gst_caps_get_structure (Handle, (uint) index);
- return (Gst.Structure) new Gst.Structure (raw_ptr);
+ if (structures.Contains (raw_ptr)) {
+ Structure ret = (Gst.Structure) structures[raw_ptr];
+
+ return ret;
+ } else {
+ Structure ret = new Gst.Structure (raw_ptr);
+
+ ret.FreeNative = false;
+ structures.Add (raw_ptr, ret);
+
+ return ret;
+ }
}
}
if (!IsWritable)
throw new ApplicationException ();
+ /* Removes all structures! */
+ if (caps.IsAny) {
+ RemoveStructureReferences ();
+ }
gst_caps_merge (Handle, gst_caps_copy (caps.Handle));
}
if (index >= Size)
throw new ArgumentOutOfRangeException ();
+ if (structures.Contains (this[index].Handle)) {
+ RemoveStructureReference (this[index]);
+ }
+
gst_caps_remove_structure (Handle, index);
}
if (!IsWritable)
throw new ApplicationException ();
+ /* FIXME: This might remove/free structures, we have to copy
+ * them before with RemoveStructureReference() somehow
+ */
+
return gst_caps_do_simplify (Handle);
}
if (!IsWritable)
throw new ApplicationException ();
+ for (uint i = 1; i < Size; i++)
+ RemoveStructureReference (this[i]);
+
gst_caps_truncate (Handle);
}
+
+[DllImport ("gstreamer-0.10.dll") ]
+static extern void gst_caps_unref (IntPtr raw);
+
+protected override void Unref (IntPtr raw) {
+ RemoveStructureReferences ();
+ if (Owned) {
+ gst_caps_unref (raw);
+ Owned = false;
+ }
+}
+
+class FinalizerInfo {
+ IntPtr handle;
+
+ public FinalizerInfo (IntPtr handle) {
+ this.handle = handle;
+ }
+
+ public bool Handler () {
+ gst_caps_unref (handle);
+ return false;
+ }
+}
+
+~Caps () {
+ if (!Owned)
+ return;
+ RemoveStructureReferences ();
+
+ FinalizerInfo info = new FinalizerInfo (Handle);
+ GLib.Timeout.Add (50, new GLib.TimeoutHandler (info.Handler));
+}
<attr path="/api/namespace/boxed[@name='Caps']/method[@cname='gst_caps_append_structure']" name="hidden">1</attr>
<attr path="/api/namespace/boxed[@name='Caps']/method[@cname='gst_caps_append']" name="hidden">1</attr>
<attr path="/api/namespace/boxed[@name='Caps']/method[@cname='gst_caps_merge']" name="hidden">1</attr>
+ <attr path="/api/namespace/boxed[@name='Caps']/method[@cname='gst_caps_unref']" name="hidden">1</attr>
<attr path="/api/namespace/boxed[@name='Caps']/method[@cname='gst_caps_intersect']/return-type" name="owned">true</attr>
<attr path="/api/namespace/boxed[@name='Caps']/method[@cname='gst_caps_union']/return-type" name="owned">true</attr>
<attr path="/api/namespace/boxed[@name='Caps']/method[@cname='gst_caps_normalize']/return-type" name="owned">true</attr>
<attr path="/api/namespace/boxed[@name='Structure']/method[@cname='gst_structure_fixate_field_nearest_fraction']" name="hidden">1</attr>
<attr path="/api/namespace/boxed[@name='Structure']/method[@cname='gst_structure_set_valist']" name="hidden">1</attr>
<attr path="/api/namespace/boxed[@name='Structure']/method[@cname='gst_structure_get_name_id']" name="hidden">1</attr>
+ <attr path="/api/namespace/boxed[@name='Structure']/method[@cname='gst_structure_free']" name="hidden">1</attr>
<change-node-type path="/api/namespace/boxed[@name='Structure']/method[@cname='gst_structure_empty_new']">constructor</change-node-type>
<remove-attr path="/api/namespace/boxed[@name='Structure']/constructor[@cname='gst_structure_empty_new']" name="name" />
<remove-attr path="/api/namespace/boxed[@name='Structure']/constructor[@cname='gst_structure_empty_new']" name="shared" />
+internal bool FreeNative = true;
+
+[DllImport ("gstreamer-0.10.dll") ]
+static extern void gst_structure_free (IntPtr raw);
+
+protected override void Free (IntPtr raw) {
+ if (!FreeNative)
+ return;
+
+ gst_structure_free (raw);
+}
+
+class FinalizerInfo {
+ IntPtr handle;
+
+ public FinalizerInfo (IntPtr handle) {
+ this.handle = handle;
+ }
+
+ public bool Handler () {
+ gst_structure_free (handle);
+ return false;
+ }
+}
+
+~Structure () {
+ if (!Owned || !FreeNative)
+ return;
+ FinalizerInfo info = new FinalizerInfo (Handle);
+ GLib.Timeout.Add (50, new GLib.TimeoutHandler (info.Handler));
+}
+
[DllImport ("gstreamer-0.10.dll") ]
static extern IntPtr gst_structure_get_name (IntPtr raw);
}
}
+internal void CreateNativeCopy () {
+ FreeNative = false;
+ Raw = gst_structure_copy (Raw);
+ FreeNative = true;
+}