mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-03 16:09:39 +00:00
Fix structure handling (almost) of caps
Make sure that we a) don't free structures of caps as we don't own them and b) make sure to create a copy of all still referenced structures before it gets removed, the caps are unreffed or something else happens. This still needs to be fixed for gst_caps_do_simplify()! This workaround is inspired by the one in gst-python.
This commit is contained in:
parent
f15f6c0091
commit
0c50db66f0
3 changed files with 113 additions and 1 deletions
|
@ -35,6 +35,7 @@ public void MakeWritable() {
|
|||
if (IsWritable)
|
||||
return;
|
||||
|
||||
RemoveStructureReferences ();
|
||||
IntPtr copy = gst_caps_copy (Raw);
|
||||
Raw = copy;
|
||||
/* ^--- Takes a second ref, not good */
|
||||
|
@ -43,6 +44,19 @@ public void MakeWritable() {
|
|||
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);
|
||||
|
||||
|
@ -53,7 +67,18 @@ public Structure this [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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,6 +156,10 @@ public void Merge (Caps caps) {
|
|||
if (!IsWritable)
|
||||
throw new ApplicationException ();
|
||||
|
||||
/* Removes all structures! */
|
||||
if (caps.IsAny) {
|
||||
RemoveStructureReferences ();
|
||||
}
|
||||
gst_caps_merge (Handle, gst_caps_copy (caps.Handle));
|
||||
}
|
||||
|
||||
|
@ -143,6 +172,10 @@ public void RemoveStructure (uint index) {
|
|||
if (index >= Size)
|
||||
throw new ArgumentOutOfRangeException ();
|
||||
|
||||
if (structures.Contains (this[index].Handle)) {
|
||||
RemoveStructureReference (this[index]);
|
||||
}
|
||||
|
||||
gst_caps_remove_structure (Handle, index);
|
||||
}
|
||||
|
||||
|
@ -153,6 +186,10 @@ public bool DoSimplify () {
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -163,5 +200,41 @@ public void Truncate () {
|
|||
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));
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
<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>
|
||||
|
@ -407,6 +408,7 @@
|
|||
<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" />
|
||||
|
|
|
@ -1,3 +1,35 @@
|
|||
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);
|
||||
|
||||
|
@ -199,3 +231,8 @@ public bool IsMutable {
|
|||
}
|
||||
}
|
||||
|
||||
internal void CreateNativeCopy () {
|
||||
FreeNative = false;
|
||||
Raw = gst_structure_copy (Raw);
|
||||
FreeNative = true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue