From e54c57a78a22e1f3a3f5ee5364278ad60ef02398 Mon Sep 17 00:00:00 2001 From: Stephan Sundermann Date: Fri, 11 Oct 2013 12:04:10 +0200 Subject: [PATCH] Gst.Value: Added support for GstFraction, GstFourcc, GstRange... --- sources/custom/Value.cs | 741 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 741 insertions(+) create mode 100644 sources/custom/Value.cs diff --git a/sources/custom/Value.cs b/sources/custom/Value.cs new file mode 100644 index 0000000000..13452445ab --- /dev/null +++ b/sources/custom/Value.cs @@ -0,0 +1,741 @@ +// Copyright (C) 2009 Sebastian Dröge +// Copyright (C) 2013 Stephan Sundermann +// +// 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