// This file was generated by the Gtk# code generator.
// Any changes made will be lost if regenerated.

namespace Gst.PbUtils {

	using System;
	using System.Collections;
	using System.Collections.Generic;
	using System.Runtime.InteropServices;

#region Autogenerated code
	public partial class EncodingVideoProfile : Gst.PbUtils.EncodingProfile {

		public EncodingVideoProfile (IntPtr raw) : base(raw) {}

		[DllImport("gstpbutils-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_encoding_video_profile_new(IntPtr format, IntPtr preset, IntPtr restriction, uint presence);

		public EncodingVideoProfile (Gst.Caps format, string preset, Gst.Caps restriction, uint presence) : base (IntPtr.Zero)
		{
			if (GetType () != typeof (EncodingVideoProfile)) {
				var vals = new List<GLib.Value> ();
				var names = new List<string> ();
				CreateNativeObject (names.ToArray (), vals.ToArray ());
				return;
			}
			IntPtr native_preset = GLib.Marshaller.StringToPtrGStrdup (preset);
			Raw = gst_encoding_video_profile_new(format == null ? IntPtr.Zero : format.Handle, native_preset, restriction == null ? IntPtr.Zero : restriction.Handle, presence);
			GLib.Marshaller.Free (native_preset);
		}


		// Internal representation of the wrapped structure ABI.
		static GLib.AbiStruct _class_abi = null;
		static public new GLib.AbiStruct class_abi {
			get {
				if (_class_abi == null)
					_class_abi = new GLib.AbiStruct (Gst.PbUtils.EncodingProfile.class_abi.Fields);

				return _class_abi;
			}
		}


		// End of the ABI representation.

		[DllImport("gstpbutils-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_encoding_video_profile_get_type();

		public static new GLib.GType GType { 
			get {
				IntPtr raw_ret = gst_encoding_video_profile_get_type();
				GLib.GType ret = new GLib.GType(raw_ret);
				return ret;
			}
		}

		[DllImport("gstpbutils-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern uint gst_encoding_video_profile_get_pass(IntPtr raw);

		[DllImport("gstpbutils-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_encoding_video_profile_set_pass(IntPtr raw, uint pass);

		public uint Pass { 
			get {
				uint raw_ret = gst_encoding_video_profile_get_pass(Handle);
				uint ret = raw_ret;
				return ret;
			}
			set {
				gst_encoding_video_profile_set_pass(Handle, value);
			}
		}

		[DllImport("gstpbutils-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_encoding_video_profile_get_variableframerate(IntPtr raw);

		[DllImport("gstpbutils-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_encoding_video_profile_set_variableframerate(IntPtr raw, bool variableframerate);

		public bool Variableframerate { 
			get {
				bool raw_ret = gst_encoding_video_profile_get_variableframerate(Handle);
				bool ret = raw_ret;
				return ret;
			}
			set {
				gst_encoding_video_profile_set_variableframerate(Handle, value);
			}
		}


		static EncodingVideoProfile ()
		{
			GtkSharp.GstreamerSharp.ObjectManager.Initialize ();
		}

		// Internal representation of the wrapped structure ABI.
		static GLib.AbiStruct _abi_info = null;
		static public new GLib.AbiStruct abi_info {
			get {
				if (_abi_info == null)
					_abi_info = new GLib.AbiStruct (Gst.PbUtils.EncodingProfile.abi_info.Fields);

				return _abi_info;
			}
		}


		// End of the ABI representation.

#endregion
	}
}
