gstreamer/gstreamer-sharp/Structure.custom
Sebastian Dröge 0c50db66f0 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.
2009-04-19 16:56:14 +02:00

238 lines
6.6 KiB
Text

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);
[DllImport ("gstreamer-0.10.dll") ]
static extern void gst_structure_set_name (IntPtr raw, IntPtr name);
public string Name {
get {
IntPtr raw_ret = gst_structure_get_name (Handle);
string ret = GLib.Marshaller.Utf8PtrToString (raw_ret);
return ret;
}
set {
if (!IsMutable)
throw new ApplicationException ();
IntPtr native_value = GLib.Marshaller.StringToPtrGStrdup (value);
gst_structure_set_name (Handle, native_value);
GLib.Marshaller.Free (native_value);
}
}
[DllImport ("gstreamer-0.10.dll") ]
static extern void gst_structure_set_value (IntPtr raw, IntPtr fieldname, IntPtr value);
public void SetValue (string fieldname, GLib.Value value) {
if (!IsMutable)
throw new ApplicationException ();
IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
IntPtr native_value = GLib.Marshaller.StructureToPtrAlloc (value);
gst_structure_set_value (Handle, native_fieldname, native_value);
GLib.Marshaller.Free (native_fieldname);
value = (GLib.Value) Marshal.PtrToStructure (native_value, typeof (GLib.Value));
Marshal.FreeHGlobal (native_value);
}
[DllImport ("gstreamer-0.10.dll") ]
static extern bool gst_structure_fixate_field_boolean (IntPtr raw, IntPtr field_name, bool target);
public bool FixateFieldBoolean (string field_name, bool target) {
if (!IsMutable)
throw new ApplicationException ();
IntPtr native_field_name = GLib.Marshaller.StringToPtrGStrdup (field_name);
bool raw_ret = gst_structure_fixate_field_boolean (Handle, native_field_name, target);
bool ret = raw_ret;
GLib.Marshaller.Free (native_field_name);
return ret;
}
[DllImport ("gstreamer-0.10.dll") ]
static extern void gst_structure_remove_all_fields (IntPtr raw);
public void RemoveAllFields() {
if (!IsMutable)
throw new ApplicationException ();
gst_structure_remove_all_fields (Handle);
}
[DllImport ("gstreamer-0.10.dll") ]
static extern void gst_structure_remove_field (IntPtr raw, IntPtr fieldname);
public void RemoveField (string fieldname) {
if (!IsMutable)
throw new ApplicationException ();
IntPtr native_fieldname = GLib.Marshaller.StringToPtrGStrdup (fieldname);
gst_structure_remove_field (Handle, native_fieldname);
GLib.Marshaller.Free (native_fieldname);
}
[DllImport ("gstreamer-0.10.dll") ]
static extern bool gst_structure_fixate_field_nearest_double (IntPtr raw, IntPtr field_name, double target);
public bool FixateFieldNearestDouble (string field_name, double target) {
if (!IsMutable)
throw new ApplicationException ();
IntPtr native_field_name = GLib.Marshaller.StringToPtrGStrdup (field_name);
bool raw_ret = gst_structure_fixate_field_nearest_double (Handle, native_field_name, target);
bool ret = raw_ret;
GLib.Marshaller.Free (native_field_name);
return ret;
}
[DllImport ("gstreamer-0.10.dll") ]
static extern bool gst_structure_fixate_field_nearest_int (IntPtr raw, IntPtr field_name, int target);
public bool FixateFieldNearestInt (string field_name, int target) {
if (!IsMutable)
throw new ApplicationException ();
IntPtr native_field_name = GLib.Marshaller.StringToPtrGStrdup (field_name);
bool raw_ret = gst_structure_fixate_field_nearest_int (Handle, native_field_name, target);
bool ret = raw_ret;
GLib.Marshaller.Free (native_field_name);
return ret;
}
[DllImport ("gstreamer-0.10.dll") ]
static extern bool gst_structure_fixate_field_nearest_fraction (IntPtr raw, IntPtr field_name, int target_numerator, int target_denominator);
public bool FixateFieldNearestFraction (string field_name, int target_numerator, int target_denominator) {
if (!IsMutable)
throw new ApplicationException ();
IntPtr native_field_name = GLib.Marshaller.StringToPtrGStrdup (field_name);
bool raw_ret = gst_structure_fixate_field_nearest_fraction (Handle, native_field_name, target_numerator, target_denominator);
bool ret = raw_ret;
GLib.Marshaller.Free (native_field_name);
return ret;
}
public Structure (string name, params object[] fields) : this (name) {
Set (fields);
}
public object Get (string field) {
GLib.Value v;
v = GetValue (field);
return v.Val;
}
public void Set (string field, object value) {
SetValue (field, new GLib.Value (value));
}
public void Set (params object[] fields) {
int i, length = fields.Length;
if (length % 2 != 0)
throw new ArgumentException ();
for (i = 0; i < length; i += 2) {
SetValue (fields[i] as string, new GLib.Value (fields[i+1]));
}
}
public object this [string field] {
set {
if (field == null)
throw new ArgumentNullException ();
Set (field, value);
}
get {
if (field == null)
throw new ArgumentNullException ();
return Get (field);
}
}
public IEnumerable Fields {
get {
ArrayList fields = new ArrayList ();
for (uint i = 0; i < Count; i++)
fields.Add (NthFieldName (i));
return fields;
}
}
public static Structure NewFromString (string structure) {
IntPtr raw_ret = gst_structure_from_string (structure, IntPtr.Zero);
Gst.Structure ret = raw_ret == IntPtr.Zero ? null : (Gst.Structure) GLib.Opaque.GetOpaque (raw_ret, typeof (Gst.Structure), false);
return ret;
}
[DllImport ("gstreamer-0.10.dll") ]
private static extern IntPtr gst_structure_from_string (string structure, IntPtr end);
public bool FixateFieldNearestFraction (string field_name, Fraction target) {
return FixateFieldNearestFraction (field_name, target.Numerator, target.Denominator);
}
[DllImport ("gstreamersharpglue-0.10") ]
extern static uint gstsharp_gst_structure_get_parent_refcount_offset ();
static uint parent_refcount_offset = gstsharp_gst_structure_get_parent_refcount_offset ();
public bool IsMutable {
get {
unsafe {
int **parent_refcount = (int **) ( ( (byte*) Handle) + parent_refcount_offset);
if (*parent_refcount == (int *) IntPtr.Zero)
return true;
if (**parent_refcount == 1)
return true;
return false;
}
}
}
internal void CreateNativeCopy () {
FreeNative = false;
Raw = gst_structure_copy (Raw);
FreeNative = true;
}