Gst.Value: Added support for GstFraction, GstFourcc, GstRange...
authorStephan Sundermann <stephansundermann@gmail.com>
Fri, 11 Oct 2013 10:04:10 +0000 (12:04 +0200)
committerStephan Sundermann <stephansundermann@gmail.com>
Sat, 21 Dec 2013 15:52:22 +0000 (16:52 +0100)
sources/custom/Value.cs [new file with mode: 0644]

diff --git a/sources/custom/Value.cs b/sources/custom/Value.cs
new file mode 100644 (file)
index 0000000..1345244
--- /dev/null
@@ -0,0 +1,741 @@
+// Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+// Copyright (C) 2013 Stephan Sundermann <stephansundermann@gmail.com>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+// Wrapper for GLib.Value to add support for GstFraction, GstFourcc, Gst*Range, ...
+using System;
+using System.Text;
+using System.Collections;
+using System.Runtime.InteropServices;
+using GLib;
+
+/* TODO: intersect, compare, substract, .... */
+namespace Gst
+{
+       public struct Fraction
+       {
+               public int Numerator {
+                       get {
+                               return numerator;
+                       }
+
+                       set {
+                               numerator = value;
+                               Reduce ();
+                       }
+               }
+
+               public int Denominator {
+                       get {
+                               return denominator;
+                       }
+
+                       set {
+                               if (denominator == 0)
+                                       throw new ArgumentException ();
+
+                               denominator = value;
+                               Reduce ();
+                       }
+               }
+
+               private int numerator;
+               private int denominator;
+
+               public static GLib.GType GType {
+                       get {
+                               return new GType (gst_fraction_get_type ());
+                       }
+               }
+
+               private void Reduce ()
+               {
+                       int gcd = GreatestCommonDivisor (this);
+
+                       if (gcd != 0) {
+                               this.numerator /= gcd;
+                               this.denominator /= gcd;
+                       }
+               }
+
+               private static int GreatestCommonDivisor (Fraction fraction)
+               {
+                       int a = fraction.numerator;
+                       int b = fraction.denominator;
+
+                       while (b != 0) {
+                               int temp = a;
+
+                               a = b;
+                               b = temp % b;
+                       }
+                       return Math.Abs (a);
+               }
+
+               public Fraction (int numerator, int denominator)
+               {
+                       if (denominator == 0)
+                               throw new ArgumentException ();
+
+                       this.numerator = numerator;
+                       this.denominator = denominator;
+                       Reduce ();
+               }
+
+               public Fraction (GLib.Value val) : this ()
+               {
+                       this.numerator = gst_value_get_fraction_numerator (ref val);
+                       this.denominator = gst_value_get_fraction_denominator (ref val);
+               }
+
+               public void SetGValue (ref GLib.Value val)
+               {
+                       gst_value_set_fraction (ref val, Numerator, Denominator);
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("{0}/{1}", numerator, denominator);
+               }
+
+               public static explicit operator GLib.Value (Fraction fraction)
+               {
+                       GLib.Value val = new GLib.Value (Fraction.GType);
+                       gst_value_set_fraction (ref val, fraction.Numerator, fraction.Denominator);
+
+                       return val;
+               }
+
+               public static explicit operator double (Fraction fraction)
+               {
+                       return ((double)fraction.numerator) / ((double)fraction.denominator);
+               }
+
+               public static Fraction operator + (Fraction a, Fraction b)
+               {
+                       return new Fraction ((a.Numerator * b.Denominator) + (b.Numerator * a.Denominator), a.Denominator * b.Denominator);
+               }
+
+               public static Fraction operator - (Fraction a, Fraction b)
+               {
+                       return new Fraction ((a.Numerator * b.Denominator) - (b.Numerator * a.Denominator), a.Denominator * b.Denominator);
+               }
+
+               public static Fraction operator * (Fraction a, Fraction b)
+               {
+                       return new Fraction (a.Numerator * b.Numerator, a.Denominator * b.Denominator);
+               }
+
+               public static Fraction operator / (Fraction a, Fraction b)
+               {
+                       return new Fraction (a.Numerator * b.Denominator, a.Denominator * b.Numerator);
+               }
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern void gst_value_set_fraction (ref GLib.Value v, int numerator, int denominator);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern int gst_value_get_fraction_numerator (ref GLib.Value v);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern int gst_value_get_fraction_denominator (ref GLib.Value v);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern IntPtr gst_fraction_get_type ();
+       }
+
+       public struct DoubleRange
+       {
+               public double Min;
+               public double Max;
+
+               public static GLib.GType GType {
+                       get {
+                               return new GType (gst_double_range_get_type ());
+                       }
+               }
+
+               public DoubleRange (double min, double max)
+               {
+                       if (min > max)
+                               throw new ArgumentException ();
+
+                       this.Min = min;
+                       this.Max = max;
+               }
+
+               public DoubleRange (GLib.Value val) : this ()
+               {
+                       this.Min = gst_value_get_double_range_min (ref val);
+                       this.Max = gst_value_get_double_range_max (ref val);
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("[{0}, {1}]", Min, Max);
+               }
+
+               public void SetGValue (ref GLib.Value val)
+               {
+                       gst_value_set_double_range (ref val, Min, Max);
+               }
+
+               public static explicit operator GLib.Value (DoubleRange range)
+               {
+                       GLib.Value val = new GLib.Value (DoubleRange.GType);
+
+                       gst_value_set_double_range (ref val, range.Min, range.Max);
+                       return val;
+               }
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern IntPtr gst_double_range_get_type ();
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern void gst_value_set_double_range (ref GLib.Value v, double min, double max);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern double gst_value_get_double_range_min (ref GLib.Value v);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern double gst_value_get_double_range_max (ref GLib.Value v);
+       }
+
+       public struct IntRange
+       {
+               public int Min;
+               public int Max;
+
+               public static GLib.GType GType {
+                       get {
+                               return new GType (gst_int_range_get_type ());
+                       }
+               }
+
+               public IntRange (int min, int max)
+               {
+                       if (min > max)
+                               throw new ArgumentException ();
+
+                       this.Min = min;
+                       this.Max = max;
+               }
+
+               public IntRange (GLib.Value val) : this ()
+               {
+                       this.Min = gst_value_get_int_range_min (ref val);
+                       this.Max = gst_value_get_int_range_max (ref val);
+               }
+
+               public void SetGValue (ref GLib.Value val)
+               {
+                       gst_value_set_int_range (ref val, Min, Max);
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("[{0}, {1}]", Min, Max);
+               }
+
+               public static explicit operator GLib.Value (IntRange range)
+               {
+                       GLib.Value val = new GLib.Value (IntRange.GType);
+
+                       gst_value_set_int_range (ref val, range.Min, range.Max);
+                       return val;
+               }
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern IntPtr gst_int_range_get_type ();
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern void gst_value_set_int_range (ref GLib.Value v, int min, int max);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern int gst_value_get_int_range_min (ref GLib.Value v);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern int gst_value_get_int_range_max (ref GLib.Value v);
+       }
+
+       public struct FractionRange
+       {
+               public Fraction Min;
+               public Fraction Max;
+
+               public static GLib.GType GType {
+                       get {
+                               return new GType (gst_fraction_range_get_type ());
+                       }
+               }
+
+               public FractionRange (Fraction min, Fraction max)
+               {
+                       double a = (double)min, b = (double)max;
+
+                       if (a > b)
+                               throw new ArgumentException ();
+
+                       this.Min = min;
+                       this.Max = max;
+               }
+
+               public FractionRange (GLib.Value val) : this ()
+               {
+                       IntPtr min_ptr, max_ptr;
+                       GLib.Value min, max;
+
+                       min_ptr = gst_value_get_fraction_range_min (ref val);
+                       max_ptr = gst_value_get_fraction_range_max (ref val);
+
+                       min = (GLib.Value)Marshal.PtrToStructure (min_ptr, typeof(GLib.Value));
+                       max = (GLib.Value)Marshal.PtrToStructure (max_ptr, typeof(GLib.Value));
+                       this.Min = (Fraction)min.Val;
+                       this.Max = (Fraction)max.Val;
+               }
+
+               public void SetGValue (ref GLib.Value val)
+               {
+                       GLib.Value min = new GLib.Value (Min);
+                       GLib.Value max = new GLib.Value (Max);
+                       gst_value_set_fraction_range (ref val, ref min, ref max);
+                       min.Dispose ();
+                       max.Dispose ();
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("[{0}, {1}]", Min, Max);
+               }
+
+               public static explicit operator GLib.Value (FractionRange range)
+               {
+                       GLib.Value val = new GLib.Value (FractionRange.GType);
+
+                       GLib.Value min = new GLib.Value (range.Min);
+                       GLib.Value max = new GLib.Value (range.Max);
+                       gst_value_set_fraction_range (ref val, ref min, ref max);
+                       min.Dispose ();
+                       max.Dispose ();
+                       return val;
+               }
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern IntPtr gst_fraction_range_get_type ();
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern void gst_value_set_fraction_range (ref GLib.Value v, ref GLib.Value min, ref GLib.Value max);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern IntPtr gst_value_get_fraction_range_min (ref GLib.Value v);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern IntPtr gst_value_get_fraction_range_max (ref GLib.Value v);
+       }
+
+       public struct Fourcc
+       {
+               public uint Val;
+
+               public static GLib.GType GType {
+                       get {
+                               return new GType (gst_fourcc_get_type ());
+                       }
+               }
+
+               public Fourcc (uint fourcc)
+               {
+                       this.Val = fourcc;
+               }
+
+               public Fourcc (char[] fourcc)
+               {
+                       if (fourcc.Length != 4)
+                               throw new ArgumentException ();
+
+                       this.Val = (uint)((((byte)fourcc [0]) << 24) |
+                               (((byte)fourcc [1]) << 16) |
+                               (((byte)fourcc [2]) << 8) |
+                               (((byte)fourcc [3]) << 0));
+               }
+
+               public Fourcc (string fourcc)
+               {
+                       if (fourcc.Length != 4)
+                               throw new ArgumentException ();
+
+                       this.Val = (uint)((((byte)fourcc [0]) << 24) |
+                               (((byte)fourcc [1]) << 16) |
+                               (((byte)fourcc [2]) << 8) |
+                               (((byte)fourcc [3]) << 0));
+               }
+
+               public Fourcc (GLib.Value val) : this (gst_value_get_fourcc (ref val))
+               {
+               }
+
+               public void SetGValue (ref GLib.Value val)
+               {
+                       gst_value_set_fourcc (ref val, Val);
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("{0}{1}{2}{3}", (char)((Val >> 24) & 0xff),
+                                             (char)((Val >> 16) & 0xff),
+                                             (char)((Val >> 8) & 0xff),
+                                             (char)((Val >> 0) & 0xff));
+               }
+
+               public static explicit operator GLib.Value (Fourcc fourcc)
+               {
+                       GLib.Value val = new GLib.Value (Fourcc.GType);
+
+                       gst_value_set_fourcc (ref val, fourcc.Val);
+                       return val;
+               }
+
+               public static explicit operator char[] (Fourcc fourcc)
+               {
+                       return new char[] { (char) ( (fourcc.Val >> 24) & 0xff),
+                               (char) ( (fourcc.Val >> 16) & 0xff),
+                               (char) ( (fourcc.Val >> 8) & 0xff),
+                               (char) ( (fourcc.Val >> 0) & 0xff)
+                       };
+               }
+
+               public static explicit operator string (Fourcc fourcc)
+               {
+                       return fourcc.ToString ();
+               }
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern IntPtr gst_fourcc_get_type ();
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern void gst_value_set_fourcc (ref GLib.Value v, uint fourcc);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern uint gst_value_get_fourcc (ref GLib.Value v);
+       }
+
+       public class Date : IWrapper
+       {
+               public DateTime Val;
+               private IntPtr handle;
+
+               public IntPtr Handle {
+                       get {
+                               return handle;
+                       }
+               }
+
+               public static GLib.GType GType {
+                       get {
+                               return new GType (gst_date_get_type ());
+                       }
+               }
+
+               ~Date ()
+               {
+                       g_date_free (handle);
+               }
+
+               public Date (DateTime date)
+               {
+                       this.Val = date;
+                       handle = g_date_new_dmy ((byte)Val.Day, (int)Val.Month, (ushort)Val.Year);
+               }
+
+               public Date (int day, int month, int year)
+               {
+                       this.Val = new DateTime (year, month, day);
+                       handle = g_date_new_dmy ((byte)Val.Day, (int)Val.Month, (ushort)Val.Year);
+               }
+
+               public Date (GLib.Value val)
+               {
+                       IntPtr date = gst_value_get_date (ref val);
+
+                       this.Val = new DateTime (g_date_get_year (date), g_date_get_month (date), g_date_get_day (date));
+                       handle = g_date_new_dmy ((byte)Val.Day, (int)Val.Month, (ushort)Val.Year);
+               }
+
+               public static Date New (IntPtr date)
+               {
+                       return new Date (g_date_get_day (date), g_date_get_month (date), g_date_get_year (date));
+               }
+
+               public void SetGValue (ref GLib.Value val)
+               {
+                       IntPtr date_ptr = g_date_new_dmy ((byte)Val.Day, (int)Val.Month, (ushort)Val.Year);
+
+                       gst_value_set_date (ref val, date_ptr);
+
+                       GLib.Marshaller.Free (date_ptr);
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("{0}-{1}-{2}", Val.Year, Val.Month, Val.Day);
+               }
+
+               public static explicit operator GLib.Value (Date date)
+               {
+                       GLib.Value val = new GLib.Value (Date.GType);
+
+                       date.SetGValue (ref val);
+
+                       return val;
+               }
+
+               [DllImport ("libglib-2.0-0.dll") ]
+               private static extern byte g_date_get_day (IntPtr date);
+
+               [DllImport ("libglib-2.0-0.dll") ]
+               private static extern int g_date_get_month (IntPtr date);
+
+               [DllImport ("libglib-2.0-0.dll") ]
+               private static extern ushort g_date_get_year (IntPtr date);
+
+               [DllImport ("libglib-2.0-0.dll") ]
+               private static extern IntPtr g_date_new_dmy (byte day, int month, ushort year);
+
+               [DllImport ("libglib-2.0-0.dll") ]
+               private static extern void g_date_free (IntPtr date);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern IntPtr gst_date_get_type ();
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern IntPtr gst_value_get_date (ref GLib.Value val);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern void gst_value_set_date (ref GLib.Value val, IntPtr date);
+       }
+
+       public struct List : IEnumerable
+       {
+               private IList content;
+
+               public static GLib.GType GType {
+                       get {
+                               return new GType (gst_value_list_get_type ());
+                       }
+               }
+
+               public List (IList content)
+               {
+                       this.content = content;
+               }
+
+               public List (GLib.Value val)
+               {
+                       this.content = new ArrayList ();
+
+                       uint n = gst_value_list_get_size (ref val);
+                       for (uint i = 0; i < n; i++) {
+                               IntPtr v_ptr = gst_value_list_get_value (ref val, i);
+                               GLib.Value v = (GLib.Value)Marshal.PtrToStructure (v_ptr, typeof(GLib.Value));
+                               this.content.Add (v.Val);
+                       }
+               }
+
+               public void SetGValue (ref GLib.Value val)
+               {
+                       foreach (object o in content) {
+                               GLib.Value v = new GLib.Value (o);
+                               gst_value_list_append_value (ref val, ref v);
+                               v.Dispose ();
+                       }
+               }
+
+               public override string ToString ()
+               {
+                       StringBuilder sb = new StringBuilder ();
+
+                       sb.Append ("< ");
+                       for (int i = 0; i < content.Count; i++) {
+                               sb.Append (content [i]);
+                               if (i < content.Count - 1)
+                                       sb.Append (", ");
+                       }
+                       sb.Append (" >");
+
+                       return sb.ToString ();
+               }
+
+               public static explicit operator GLib.Value (List l)
+               {
+                       GLib.Value val = new GLib.Value (List.GType);
+
+                       foreach (object o in l.content) {
+                               GLib.Value v = new GLib.Value (o);
+                               gst_value_list_append_value (ref val, ref v);
+                               v.Dispose ();
+                       }
+
+                       return val;
+               }
+
+               public IEnumerator GetEnumerator ()
+               {
+                       return content.GetEnumerator ();
+               }
+
+               public object this [int index] {
+                       set {
+                               content [index] = value;
+                       }
+                       get {
+                               return content [index];
+                       }
+               }
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern IntPtr gst_value_list_get_type ();
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern uint gst_value_list_get_size (ref GLib.Value val);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern IntPtr gst_value_list_get_value (ref GLib.Value val, uint index);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern void gst_value_list_append_value (ref GLib.Value val, ref GLib.Value el);
+       }
+
+       public struct Array : IEnumerable
+       {
+               private IList content;
+
+               public static GLib.GType GType {
+                       get {
+                               return new GType (gst_value_array_get_type ());
+                       }
+               }
+
+               public Array (IList content)
+               {
+                       this.content = content;
+               }
+
+               public Array (GLib.Value val)
+               {
+                       this.content = new ArrayList ();
+
+                       uint n = gst_value_array_get_size (ref val);
+                       for (uint i = 0; i < n; i++) {
+                               IntPtr v_ptr = gst_value_array_get_value (ref val, i);
+                               GLib.Value v = (GLib.Value)Marshal.PtrToStructure (v_ptr, typeof(GLib.Value));
+                               this.content.Add (v.Val);
+                       }
+               }
+
+               public void SetGValue (ref GLib.Value val)
+               {
+                       foreach (object o in content) {
+                               GLib.Value v = new GLib.Value (o);
+                               gst_value_array_append_value (ref val, ref v);
+                               v.Dispose ();
+                       }
+               }
+
+               public static explicit operator GLib.Value (Array a)
+               {
+                       GLib.Value val = new GLib.Value (Gst.Array.GType);
+
+                       foreach (object o in a.content) {
+                               GLib.Value v = new GLib.Value (o);
+                               gst_value_array_append_value (ref val, ref v);
+                               v.Dispose ();
+                       }
+
+                       return val;
+               }
+
+               public override string ToString ()
+               {
+                       StringBuilder sb = new StringBuilder ();
+
+                       sb.Append ("{ ");
+                       for (int i = 0; i < content.Count; i++) {
+                               sb.Append (content [i]);
+                               if (i < content.Count - 1)
+                                       sb.Append (", ");
+                       }
+                       sb.Append (" }");
+
+                       return sb.ToString ();
+               }
+
+               public IEnumerator GetEnumerator ()
+               {
+                       return content.GetEnumerator ();
+               }
+
+               public object this [int index] {
+                       set {
+                               content [index] = value;
+                       }
+                       get {
+                               return content [index];
+                       }
+               }
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern IntPtr gst_value_array_get_type ();
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern uint gst_value_array_get_size (ref GLib.Value val);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern IntPtr gst_value_array_get_value (ref GLib.Value val, uint index);
+
+               [DllImport("libgstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
+
+               private static extern void gst_value_array_append_value (ref GLib.Value val, ref GLib.Value el);
+       }
+}
\ No newline at end of file