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

namespace Gst.Audio {

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

#region Autogenerated code
	public partial class AudioEncoder : Gst.Element, Gst.IPreset {

		protected AudioEncoder (IntPtr raw) : base(raw) {}

		protected AudioEncoder() : base(IntPtr.Zero)
		{
			CreateNativeObject (new string [0], new GLib.Value [0]);
		}

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

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_set_hard_resync(IntPtr raw, bool enabled);

		[GLib.Property ("hard-resync")]
		public bool HardResync {
			get  {
				bool raw_ret = gst_audio_encoder_get_hard_resync(Handle);
				bool ret = raw_ret;
				return ret;
			}
			set  {
				gst_audio_encoder_set_hard_resync(Handle, value);
			}
		}

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

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_set_mark_granule(IntPtr raw, bool enabled);

		[GLib.Property ("mark-granule")]
		public bool MarkGranule {
			get  {
				bool raw_ret = gst_audio_encoder_get_mark_granule(Handle);
				bool ret = raw_ret;
				return ret;
			}
			set  {
				gst_audio_encoder_set_mark_granule(Handle, value);
			}
		}

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

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_set_perfect_timestamp(IntPtr raw, bool enabled);

		[GLib.Property ("perfect-timestamp")]
		public bool PerfectTimestamp {
			get  {
				bool raw_ret = gst_audio_encoder_get_perfect_timestamp(Handle);
				bool ret = raw_ret;
				return ret;
			}
			set  {
				gst_audio_encoder_set_perfect_timestamp(Handle, value);
			}
		}

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern ulong gst_audio_encoder_get_tolerance(IntPtr raw);

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_set_tolerance(IntPtr raw, ulong tolerance);

		[GLib.Property ("tolerance")]
		public ulong Tolerance {
			get  {
				ulong raw_ret = gst_audio_encoder_get_tolerance(Handle);
				ulong ret = raw_ret;
				return ret;
			}
			set  {
				gst_audio_encoder_set_tolerance(Handle, value);
			}
		}

		public Gst.Pad Sinkpad {
			get {
				unsafe {
					IntPtr* raw_ptr = (IntPtr*)(((byte*)Handle) + abi_info.GetFieldOffset("sinkpad"));
					return GLib.Object.GetObject((*raw_ptr)) as Gst.Pad;
				}
			}
		}

		public Gst.Pad Srcpad {
			get {
				unsafe {
					IntPtr* raw_ptr = (IntPtr*)(((byte*)Handle) + abi_info.GetFieldOffset("srcpad"));
					return GLib.Object.GetObject((*raw_ptr)) as Gst.Pad;
				}
			}
		}

		public GLib.RecMutex StreamLock {
			get {
				unsafe {
					IntPtr* raw_ptr = (IntPtr*)(((byte*)Handle) + abi_info.GetFieldOffset("stream_lock"));
					return new GLib.RecMutex((*raw_ptr));
				}
			}
		}

		public Gst.Segment InputSegment {
			get {
				unsafe {
					IntPtr* raw_ptr = (IntPtr*)(((byte*)Handle) + abi_info.GetFieldOffset("input_segment"));
					return Gst.Segment.New ((*raw_ptr));
				}
			}
		}

		public Gst.Segment OutputSegment {
			get {
				unsafe {
					IntPtr* raw_ptr = (IntPtr*)(((byte*)Handle) + abi_info.GetFieldOffset("output_segment"));
					return Gst.Segment.New ((*raw_ptr));
				}
			}
		}

		static StartNativeDelegate Start_cb_delegate;
		static StartNativeDelegate StartVMCallback {
			get {
				if (Start_cb_delegate == null)
					Start_cb_delegate = new StartNativeDelegate (Start_cb);
				return Start_cb_delegate;
			}
		}

		static void OverrideStart (GLib.GType gtype)
		{
			OverrideStart (gtype, StartVMCallback);
		}

		static void OverrideStart (GLib.GType gtype, StartNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("start"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool StartNativeDelegate (IntPtr inst);

		static bool Start_cb (IntPtr inst)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				bool __result;
				__result = __obj.OnStart ();
				return __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideStart")]
		protected virtual bool OnStart ()
		{
			return InternalStart ();
		}

		private bool InternalStart ()
		{
			StartNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("start"));
				unmanaged = (StartNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(StartNativeDelegate));
			}
			if (unmanaged == null) return false;

			bool __result = unmanaged (this.Handle);
			return __result;
		}

		static StopNativeDelegate Stop_cb_delegate;
		static StopNativeDelegate StopVMCallback {
			get {
				if (Stop_cb_delegate == null)
					Stop_cb_delegate = new StopNativeDelegate (Stop_cb);
				return Stop_cb_delegate;
			}
		}

		static void OverrideStop (GLib.GType gtype)
		{
			OverrideStop (gtype, StopVMCallback);
		}

		static void OverrideStop (GLib.GType gtype, StopNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("stop"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool StopNativeDelegate (IntPtr inst);

		static bool Stop_cb (IntPtr inst)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				bool __result;
				__result = __obj.OnStop ();
				return __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideStop")]
		protected virtual bool OnStop ()
		{
			return InternalStop ();
		}

		private bool InternalStop ()
		{
			StopNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("stop"));
				unmanaged = (StopNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(StopNativeDelegate));
			}
			if (unmanaged == null) return false;

			bool __result = unmanaged (this.Handle);
			return __result;
		}

		static SetFormatNativeDelegate SetFormat_cb_delegate;
		static SetFormatNativeDelegate SetFormatVMCallback {
			get {
				if (SetFormat_cb_delegate == null)
					SetFormat_cb_delegate = new SetFormatNativeDelegate (SetFormat_cb);
				return SetFormat_cb_delegate;
			}
		}

		static void OverrideSetFormat (GLib.GType gtype)
		{
			OverrideSetFormat (gtype, SetFormatVMCallback);
		}

		static void OverrideSetFormat (GLib.GType gtype, SetFormatNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("set_format"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool SetFormatNativeDelegate (IntPtr inst, IntPtr info);

		static bool SetFormat_cb (IntPtr inst, IntPtr info)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				bool __result;
				__result = __obj.OnSetFormat (info == IntPtr.Zero ? null : (Gst.Audio.AudioInfo) GLib.Opaque.GetOpaque (info, typeof (Gst.Audio.AudioInfo), false));
				return __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideSetFormat")]
		protected virtual bool OnSetFormat (Gst.Audio.AudioInfo info)
		{
			return InternalSetFormat (info);
		}

		private bool InternalSetFormat (Gst.Audio.AudioInfo info)
		{
			SetFormatNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("set_format"));
				unmanaged = (SetFormatNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(SetFormatNativeDelegate));
			}
			if (unmanaged == null) return false;

			bool __result = unmanaged (this.Handle, info == null ? IntPtr.Zero : info.Handle);
			return __result;
		}

		static HandleFrameNativeDelegate HandleFrame_cb_delegate;
		static HandleFrameNativeDelegate HandleFrameVMCallback {
			get {
				if (HandleFrame_cb_delegate == null)
					HandleFrame_cb_delegate = new HandleFrameNativeDelegate (HandleFrame_cb);
				return HandleFrame_cb_delegate;
			}
		}

		static void OverrideHandleFrame (GLib.GType gtype)
		{
			OverrideHandleFrame (gtype, HandleFrameVMCallback);
		}

		static void OverrideHandleFrame (GLib.GType gtype, HandleFrameNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("handle_frame"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate int HandleFrameNativeDelegate (IntPtr inst, IntPtr buffer);

		static int HandleFrame_cb (IntPtr inst, IntPtr buffer)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				Gst.FlowReturn __result;
				__result = __obj.OnHandleFrame (buffer == IntPtr.Zero ? null : (Gst.Buffer) GLib.Opaque.GetOpaque (buffer, typeof (Gst.Buffer), false));
				return (int) __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideHandleFrame")]
		protected virtual Gst.FlowReturn OnHandleFrame (Gst.Buffer buffer)
		{
			return InternalHandleFrame (buffer);
		}

		private Gst.FlowReturn InternalHandleFrame (Gst.Buffer buffer)
		{
			HandleFrameNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("handle_frame"));
				unmanaged = (HandleFrameNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(HandleFrameNativeDelegate));
			}
			if (unmanaged == null) return (Gst.FlowReturn) 0;

			int __result = unmanaged (this.Handle, buffer == null ? IntPtr.Zero : buffer.Handle);
			return (Gst.FlowReturn) __result;
		}

		static FlushNativeDelegate Flush_cb_delegate;
		static FlushNativeDelegate FlushVMCallback {
			get {
				if (Flush_cb_delegate == null)
					Flush_cb_delegate = new FlushNativeDelegate (Flush_cb);
				return Flush_cb_delegate;
			}
		}

		static void OverrideFlush (GLib.GType gtype)
		{
			OverrideFlush (gtype, FlushVMCallback);
		}

		static void OverrideFlush (GLib.GType gtype, FlushNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("flush"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate void FlushNativeDelegate (IntPtr inst);

		static void Flush_cb (IntPtr inst)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				__obj.OnFlush ();
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, false);
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideFlush")]
		protected virtual void OnFlush ()
		{
			InternalFlush ();
		}

		private void InternalFlush ()
		{
			FlushNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("flush"));
				unmanaged = (FlushNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(FlushNativeDelegate));
			}
			if (unmanaged == null) return;

			unmanaged (this.Handle);
		}

		static PrePushNativeDelegate PrePush_cb_delegate;
		static PrePushNativeDelegate PrePushVMCallback {
			get {
				if (PrePush_cb_delegate == null)
					PrePush_cb_delegate = new PrePushNativeDelegate (PrePush_cb);
				return PrePush_cb_delegate;
			}
		}

		static void OverridePrePush (GLib.GType gtype)
		{
			OverridePrePush (gtype, PrePushVMCallback);
		}

		static void OverridePrePush (GLib.GType gtype, PrePushNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("pre_push"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate int PrePushNativeDelegate (IntPtr inst, IntPtr buffer);

		static int PrePush_cb (IntPtr inst, IntPtr buffer)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				Gst.FlowReturn __result;
				__result = __obj.OnPrePush (buffer == IntPtr.Zero ? null : (Gst.Buffer) GLib.Opaque.GetOpaque (buffer, typeof (Gst.Buffer), false));
				return (int) __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverridePrePush")]
		protected virtual Gst.FlowReturn OnPrePush (Gst.Buffer buffer)
		{
			return InternalPrePush (buffer);
		}

		private Gst.FlowReturn InternalPrePush (Gst.Buffer buffer)
		{
			PrePushNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("pre_push"));
				unmanaged = (PrePushNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(PrePushNativeDelegate));
			}
			if (unmanaged == null) return (Gst.FlowReturn) 0;

			int __result = unmanaged (this.Handle, buffer == null ? IntPtr.Zero : buffer.Handle);
			return (Gst.FlowReturn) __result;
		}

		static SinkEventNativeDelegate SinkEvent_cb_delegate;
		static SinkEventNativeDelegate SinkEventVMCallback {
			get {
				if (SinkEvent_cb_delegate == null)
					SinkEvent_cb_delegate = new SinkEventNativeDelegate (SinkEvent_cb);
				return SinkEvent_cb_delegate;
			}
		}

		static void OverrideSinkEvent (GLib.GType gtype)
		{
			OverrideSinkEvent (gtype, SinkEventVMCallback);
		}

		static void OverrideSinkEvent (GLib.GType gtype, SinkEventNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("sink_event"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool SinkEventNativeDelegate (IntPtr inst, IntPtr evnt);

		static bool SinkEvent_cb (IntPtr inst, IntPtr evnt)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				bool __result;
				__result = __obj.OnSinkEvent (evnt == IntPtr.Zero ? null : (Gst.Event) GLib.Opaque.GetOpaque (evnt, typeof (Gst.Event), false));
				return __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideSinkEvent")]
		protected virtual bool OnSinkEvent (Gst.Event evnt)
		{
			return InternalSinkEvent (evnt);
		}

		private bool InternalSinkEvent (Gst.Event evnt)
		{
			SinkEventNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("sink_event"));
				unmanaged = (SinkEventNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(SinkEventNativeDelegate));
			}
			if (unmanaged == null) return false;

			bool __result = unmanaged (this.Handle, evnt == null ? IntPtr.Zero : evnt.Handle);
			return __result;
		}

		static SrcEventNativeDelegate SrcEvent_cb_delegate;
		static SrcEventNativeDelegate SrcEventVMCallback {
			get {
				if (SrcEvent_cb_delegate == null)
					SrcEvent_cb_delegate = new SrcEventNativeDelegate (SrcEvent_cb);
				return SrcEvent_cb_delegate;
			}
		}

		static void OverrideSrcEvent (GLib.GType gtype)
		{
			OverrideSrcEvent (gtype, SrcEventVMCallback);
		}

		static void OverrideSrcEvent (GLib.GType gtype, SrcEventNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("src_event"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool SrcEventNativeDelegate (IntPtr inst, IntPtr evnt);

		static bool SrcEvent_cb (IntPtr inst, IntPtr evnt)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				bool __result;
				__result = __obj.OnSrcEvent (evnt == IntPtr.Zero ? null : (Gst.Event) GLib.Opaque.GetOpaque (evnt, typeof (Gst.Event), false));
				return __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideSrcEvent")]
		protected virtual bool OnSrcEvent (Gst.Event evnt)
		{
			return InternalSrcEvent (evnt);
		}

		private bool InternalSrcEvent (Gst.Event evnt)
		{
			SrcEventNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("src_event"));
				unmanaged = (SrcEventNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(SrcEventNativeDelegate));
			}
			if (unmanaged == null) return false;

			bool __result = unmanaged (this.Handle, evnt == null ? IntPtr.Zero : evnt.Handle);
			return __result;
		}

		static GetcapsNativeDelegate Getcaps_cb_delegate;
		static GetcapsNativeDelegate GetcapsVMCallback {
			get {
				if (Getcaps_cb_delegate == null)
					Getcaps_cb_delegate = new GetcapsNativeDelegate (Getcaps_cb);
				return Getcaps_cb_delegate;
			}
		}

		static void OverrideGetcaps (GLib.GType gtype)
		{
			OverrideGetcaps (gtype, GetcapsVMCallback);
		}

		static void OverrideGetcaps (GLib.GType gtype, GetcapsNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("getcaps"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate IntPtr GetcapsNativeDelegate (IntPtr inst, IntPtr filter);

		static IntPtr Getcaps_cb (IntPtr inst, IntPtr filter)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				Gst.Caps __result;
				__result = __obj.OnGetcaps (filter == IntPtr.Zero ? null : (Gst.Caps) GLib.Opaque.GetOpaque (filter, typeof (Gst.Caps), false));
				return __result == null ? IntPtr.Zero : __result.OwnedCopy;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideGetcaps")]
		protected virtual Gst.Caps OnGetcaps (Gst.Caps filter)
		{
			return InternalGetcaps (filter);
		}

		private Gst.Caps InternalGetcaps (Gst.Caps filter)
		{
			GetcapsNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("getcaps"));
				unmanaged = (GetcapsNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(GetcapsNativeDelegate));
			}
			if (unmanaged == null) return null;

			IntPtr __result = unmanaged (this.Handle, filter == null ? IntPtr.Zero : filter.Handle);
			return __result == IntPtr.Zero ? null : (Gst.Caps) GLib.Opaque.GetOpaque (__result, typeof (Gst.Caps), true);
		}

		static OpenNativeDelegate Open_cb_delegate;
		static OpenNativeDelegate OpenVMCallback {
			get {
				if (Open_cb_delegate == null)
					Open_cb_delegate = new OpenNativeDelegate (Open_cb);
				return Open_cb_delegate;
			}
		}

		static void OverrideOpen (GLib.GType gtype)
		{
			OverrideOpen (gtype, OpenVMCallback);
		}

		static void OverrideOpen (GLib.GType gtype, OpenNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("open"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool OpenNativeDelegate (IntPtr inst);

		static bool Open_cb (IntPtr inst)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				bool __result;
				__result = __obj.OnOpen ();
				return __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideOpen")]
		protected virtual bool OnOpen ()
		{
			return InternalOpen ();
		}

		private bool InternalOpen ()
		{
			OpenNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("open"));
				unmanaged = (OpenNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(OpenNativeDelegate));
			}
			if (unmanaged == null) return false;

			bool __result = unmanaged (this.Handle);
			return __result;
		}

		static CloseNativeDelegate Close_cb_delegate;
		static CloseNativeDelegate CloseVMCallback {
			get {
				if (Close_cb_delegate == null)
					Close_cb_delegate = new CloseNativeDelegate (Close_cb);
				return Close_cb_delegate;
			}
		}

		static void OverrideClose (GLib.GType gtype)
		{
			OverrideClose (gtype, CloseVMCallback);
		}

		static void OverrideClose (GLib.GType gtype, CloseNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("close"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool CloseNativeDelegate (IntPtr inst);

		static bool Close_cb (IntPtr inst)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				bool __result;
				__result = __obj.OnClose ();
				return __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideClose")]
		protected virtual bool OnClose ()
		{
			return InternalClose ();
		}

		private bool InternalClose ()
		{
			CloseNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("close"));
				unmanaged = (CloseNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(CloseNativeDelegate));
			}
			if (unmanaged == null) return false;

			bool __result = unmanaged (this.Handle);
			return __result;
		}

		static NegotiateNativeDelegate Negotiate_cb_delegate;
		static NegotiateNativeDelegate NegotiateVMCallback {
			get {
				if (Negotiate_cb_delegate == null)
					Negotiate_cb_delegate = new NegotiateNativeDelegate (Negotiate_cb);
				return Negotiate_cb_delegate;
			}
		}

		static void OverrideNegotiate (GLib.GType gtype)
		{
			OverrideNegotiate (gtype, NegotiateVMCallback);
		}

		static void OverrideNegotiate (GLib.GType gtype, NegotiateNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("negotiate"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool NegotiateNativeDelegate (IntPtr inst);

		static bool Negotiate_cb (IntPtr inst)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				bool __result;
				__result = __obj.OnNegotiate ();
				return __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideNegotiate")]
		protected virtual bool OnNegotiate ()
		{
			return InternalNegotiate ();
		}

		private bool InternalNegotiate ()
		{
			NegotiateNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("negotiate"));
				unmanaged = (NegotiateNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(NegotiateNativeDelegate));
			}
			if (unmanaged == null) return false;

			bool __result = unmanaged (this.Handle);
			return __result;
		}

		static DecideAllocationNativeDelegate DecideAllocation_cb_delegate;
		static DecideAllocationNativeDelegate DecideAllocationVMCallback {
			get {
				if (DecideAllocation_cb_delegate == null)
					DecideAllocation_cb_delegate = new DecideAllocationNativeDelegate (DecideAllocation_cb);
				return DecideAllocation_cb_delegate;
			}
		}

		static void OverrideDecideAllocation (GLib.GType gtype)
		{
			OverrideDecideAllocation (gtype, DecideAllocationVMCallback);
		}

		static void OverrideDecideAllocation (GLib.GType gtype, DecideAllocationNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("decide_allocation"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool DecideAllocationNativeDelegate (IntPtr inst, IntPtr query);

		static bool DecideAllocation_cb (IntPtr inst, IntPtr query)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				bool __result;
				__result = __obj.OnDecideAllocation (query == IntPtr.Zero ? null : (Gst.Query) GLib.Opaque.GetOpaque (query, typeof (Gst.Query), false));
				return __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideDecideAllocation")]
		protected virtual bool OnDecideAllocation (Gst.Query query)
		{
			return InternalDecideAllocation (query);
		}

		private bool InternalDecideAllocation (Gst.Query query)
		{
			DecideAllocationNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("decide_allocation"));
				unmanaged = (DecideAllocationNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(DecideAllocationNativeDelegate));
			}
			if (unmanaged == null) return false;

			bool __result = unmanaged (this.Handle, query == null ? IntPtr.Zero : query.Handle);
			return __result;
		}

		static ProposeAllocationNativeDelegate ProposeAllocation_cb_delegate;
		static ProposeAllocationNativeDelegate ProposeAllocationVMCallback {
			get {
				if (ProposeAllocation_cb_delegate == null)
					ProposeAllocation_cb_delegate = new ProposeAllocationNativeDelegate (ProposeAllocation_cb);
				return ProposeAllocation_cb_delegate;
			}
		}

		static void OverrideProposeAllocation (GLib.GType gtype)
		{
			OverrideProposeAllocation (gtype, ProposeAllocationVMCallback);
		}

		static void OverrideProposeAllocation (GLib.GType gtype, ProposeAllocationNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("propose_allocation"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool ProposeAllocationNativeDelegate (IntPtr inst, IntPtr query);

		static bool ProposeAllocation_cb (IntPtr inst, IntPtr query)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				bool __result;
				__result = __obj.OnProposeAllocation (query == IntPtr.Zero ? null : (Gst.Query) GLib.Opaque.GetOpaque (query, typeof (Gst.Query), false));
				return __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideProposeAllocation")]
		protected virtual bool OnProposeAllocation (Gst.Query query)
		{
			return InternalProposeAllocation (query);
		}

		private bool InternalProposeAllocation (Gst.Query query)
		{
			ProposeAllocationNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("propose_allocation"));
				unmanaged = (ProposeAllocationNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(ProposeAllocationNativeDelegate));
			}
			if (unmanaged == null) return false;

			bool __result = unmanaged (this.Handle, query == null ? IntPtr.Zero : query.Handle);
			return __result;
		}

		static TransformMetaNativeDelegate TransformMeta_cb_delegate;
		static TransformMetaNativeDelegate TransformMetaVMCallback {
			get {
				if (TransformMeta_cb_delegate == null)
					TransformMeta_cb_delegate = new TransformMetaNativeDelegate (TransformMeta_cb);
				return TransformMeta_cb_delegate;
			}
		}

		static void OverrideTransformMeta (GLib.GType gtype)
		{
			OverrideTransformMeta (gtype, TransformMetaVMCallback);
		}

		static void OverrideTransformMeta (GLib.GType gtype, TransformMetaNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("transform_meta"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool TransformMetaNativeDelegate (IntPtr inst, IntPtr outbuf, IntPtr meta, IntPtr inbuf);

		static bool TransformMeta_cb (IntPtr inst, IntPtr outbuf, IntPtr meta, IntPtr inbuf)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				bool __result;
				__result = __obj.OnTransformMeta (outbuf == IntPtr.Zero ? null : (Gst.Buffer) GLib.Opaque.GetOpaque (outbuf, typeof (Gst.Buffer), false), Gst.Meta.New (meta), inbuf == IntPtr.Zero ? null : (Gst.Buffer) GLib.Opaque.GetOpaque (inbuf, typeof (Gst.Buffer), false));
				return __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideTransformMeta")]
		protected virtual bool OnTransformMeta (Gst.Buffer outbuf, Gst.Meta meta, Gst.Buffer inbuf)
		{
			return InternalTransformMeta (outbuf, meta, inbuf);
		}

		private bool InternalTransformMeta (Gst.Buffer outbuf, Gst.Meta meta, Gst.Buffer inbuf)
		{
			TransformMetaNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("transform_meta"));
				unmanaged = (TransformMetaNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(TransformMetaNativeDelegate));
			}
			if (unmanaged == null) return false;

			IntPtr native_meta = GLib.Marshaller.StructureToPtrAlloc (meta);
			bool __result = unmanaged (this.Handle, outbuf == null ? IntPtr.Zero : outbuf.Handle, native_meta, inbuf == null ? IntPtr.Zero : inbuf.Handle);
			Marshal.FreeHGlobal (native_meta);
			return __result;
		}

		static SinkQueryNativeDelegate SinkQuery_cb_delegate;
		static SinkQueryNativeDelegate SinkQueryVMCallback {
			get {
				if (SinkQuery_cb_delegate == null)
					SinkQuery_cb_delegate = new SinkQueryNativeDelegate (SinkQuery_cb);
				return SinkQuery_cb_delegate;
			}
		}

		static void OverrideSinkQuery (GLib.GType gtype)
		{
			OverrideSinkQuery (gtype, SinkQueryVMCallback);
		}

		static void OverrideSinkQuery (GLib.GType gtype, SinkQueryNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("sink_query"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool SinkQueryNativeDelegate (IntPtr inst, IntPtr query);

		static bool SinkQuery_cb (IntPtr inst, IntPtr query)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				bool __result;
				__result = __obj.OnSinkQuery (query == IntPtr.Zero ? null : (Gst.Query) GLib.Opaque.GetOpaque (query, typeof (Gst.Query), false));
				return __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideSinkQuery")]
		protected virtual bool OnSinkQuery (Gst.Query query)
		{
			return InternalSinkQuery (query);
		}

		private bool InternalSinkQuery (Gst.Query query)
		{
			SinkQueryNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("sink_query"));
				unmanaged = (SinkQueryNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(SinkQueryNativeDelegate));
			}
			if (unmanaged == null) return false;

			bool __result = unmanaged (this.Handle, query == null ? IntPtr.Zero : query.Handle);
			return __result;
		}

		static SrcQueryNativeDelegate SrcQuery_cb_delegate;
		static SrcQueryNativeDelegate SrcQueryVMCallback {
			get {
				if (SrcQuery_cb_delegate == null)
					SrcQuery_cb_delegate = new SrcQueryNativeDelegate (SrcQuery_cb);
				return SrcQuery_cb_delegate;
			}
		}

		static void OverrideSrcQuery (GLib.GType gtype)
		{
			OverrideSrcQuery (gtype, SrcQueryVMCallback);
		}

		static void OverrideSrcQuery (GLib.GType gtype, SrcQueryNativeDelegate callback)
		{
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) gtype.GetClassPtr()) + (long) class_abi.GetFieldOffset("src_query"));
				*raw_ptr = Marshal.GetFunctionPointerForDelegate((Delegate) callback);
			}
		}

		[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
		delegate bool SrcQueryNativeDelegate (IntPtr inst, IntPtr query);

		static bool SrcQuery_cb (IntPtr inst, IntPtr query)
		{
			try {
				AudioEncoder __obj = GLib.Object.GetObject (inst, false) as AudioEncoder;
				bool __result;
				__result = __obj.OnSrcQuery (query == IntPtr.Zero ? null : (Gst.Query) GLib.Opaque.GetOpaque (query, typeof (Gst.Query), false));
				return __result;
			} catch (Exception e) {
				GLib.ExceptionManager.RaiseUnhandledException (e, true);
				// NOTREACHED: above call does not return.
				throw e;
			}
		}

		[GLib.DefaultSignalHandler(Type=typeof(Gst.Audio.AudioEncoder), ConnectionMethod="OverrideSrcQuery")]
		protected virtual bool OnSrcQuery (Gst.Query query)
		{
			return InternalSrcQuery (query);
		}

		private bool InternalSrcQuery (Gst.Query query)
		{
			SrcQueryNativeDelegate unmanaged = null;
			unsafe {
				IntPtr* raw_ptr = (IntPtr*)(((long) this.LookupGType().GetThresholdType().GetClassPtr()) + (long) class_abi.GetFieldOffset("src_query"));
				unmanaged = (SrcQueryNativeDelegate) Marshal.GetDelegateForFunctionPointer(*raw_ptr, typeof(SrcQueryNativeDelegate));
			}
			if (unmanaged == null) return false;

			bool __result = unmanaged (this.Handle, query == null ? IntPtr.Zero : query.Handle);
			return __result;
		}


		// 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 (new List<GLib.AbiField>{ 
						new GLib.AbiField("start"
							, Gst.Element.class_abi.Fields
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // start
							, null
							, "stop"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("stop"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // stop
							, "start"
							, "set_format"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("set_format"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // set_format
							, "stop"
							, "handle_frame"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("handle_frame"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // handle_frame
							, "set_format"
							, "flush"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("flush"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // flush
							, "handle_frame"
							, "pre_push"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("pre_push"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // pre_push
							, "flush"
							, "sink_event"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("sink_event"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // sink_event
							, "pre_push"
							, "src_event"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("src_event"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // src_event
							, "sink_event"
							, "getcaps"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("getcaps"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // getcaps
							, "src_event"
							, "open"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("open"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // open
							, "getcaps"
							, "close"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("close"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // close
							, "open"
							, "negotiate"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("negotiate"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // negotiate
							, "close"
							, "decide_allocation"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("decide_allocation"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // decide_allocation
							, "negotiate"
							, "propose_allocation"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("propose_allocation"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // propose_allocation
							, "decide_allocation"
							, "transform_meta"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("transform_meta"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // transform_meta
							, "propose_allocation"
							, "sink_query"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("sink_query"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // sink_query
							, "transform_meta"
							, "src_query"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("src_query"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // src_query
							, "sink_query"
							, "_gst_reserved"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("_gst_reserved"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) * 17 // _gst_reserved
							, "src_query"
							, null
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
					});

				return _class_abi;
			}
		}


		// End of the ABI representation.

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

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

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_audio_encoder_allocate_output_buffer(IntPtr raw, UIntPtr size);

		public Gst.Buffer AllocateOutputBuffer(ulong size) {
			IntPtr raw_ret = gst_audio_encoder_allocate_output_buffer(Handle, new UIntPtr (size));
			Gst.Buffer ret = raw_ret == IntPtr.Zero ? null : (Gst.Buffer) GLib.Opaque.GetOpaque (raw_ret, typeof (Gst.Buffer), true);
			return ret;
		}

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern int gst_audio_encoder_finish_frame(IntPtr raw, IntPtr buffer, int samples);

		public Gst.FlowReturn FinishFrame(Gst.Buffer buffer, int samples) {
			buffer.Owned = false;
			int raw_ret = gst_audio_encoder_finish_frame(Handle, buffer == null ? IntPtr.Zero : buffer.Handle, samples);
			Gst.FlowReturn ret = (Gst.FlowReturn) raw_ret;
			return ret;
		}

		public Gst.FlowReturn FinishFrame(int samples) {
			return FinishFrame (null, samples);
		}

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_get_allocator(IntPtr raw, out IntPtr allocator, IntPtr parms);

		public void GetAllocator(out Gst.Allocator allocator, out Gst.AllocationParams parms) {
			IntPtr native_allocator;
			IntPtr native_parms = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (Gst.AllocationParams)));
			gst_audio_encoder_get_allocator(Handle, out native_allocator, native_parms);
			allocator = GLib.Object.GetObject(native_allocator, true) as Gst.Allocator;
			parms = Gst.AllocationParams.New (native_parms);
			Marshal.FreeHGlobal (native_parms);
		}

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

		public Gst.Audio.AudioInfo AudioInfo { 
			get {
				IntPtr raw_ret = gst_audio_encoder_get_audio_info(Handle);
				Gst.Audio.AudioInfo ret = raw_ret == IntPtr.Zero ? null : (Gst.Audio.AudioInfo) GLib.Opaque.GetOpaque (raw_ret, typeof (Gst.Audio.AudioInfo), false);
				return ret;
			}
		}

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

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_set_drainable(IntPtr raw, bool enabled);

		public bool Drainable { 
			get {
				bool raw_ret = gst_audio_encoder_get_drainable(Handle);
				bool ret = raw_ret;
				return ret;
			}
			set {
				gst_audio_encoder_set_drainable(Handle, value);
			}
		}

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern int gst_audio_encoder_get_frame_max(IntPtr raw);

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_set_frame_max(IntPtr raw, int num);

		public int FrameMax { 
			get {
				int raw_ret = gst_audio_encoder_get_frame_max(Handle);
				int ret = raw_ret;
				return ret;
			}
			set {
				gst_audio_encoder_set_frame_max(Handle, value);
			}
		}

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern int gst_audio_encoder_get_frame_samples_max(IntPtr raw);

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_set_frame_samples_max(IntPtr raw, int num);

		public int FrameSamplesMax { 
			get {
				int raw_ret = gst_audio_encoder_get_frame_samples_max(Handle);
				int ret = raw_ret;
				return ret;
			}
			set {
				gst_audio_encoder_set_frame_samples_max(Handle, value);
			}
		}

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern int gst_audio_encoder_get_frame_samples_min(IntPtr raw);

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_set_frame_samples_min(IntPtr raw, int num);

		public int FrameSamplesMin { 
			get {
				int raw_ret = gst_audio_encoder_get_frame_samples_min(Handle);
				int ret = raw_ret;
				return ret;
			}
			set {
				gst_audio_encoder_set_frame_samples_min(Handle, value);
			}
		}

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

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_set_hard_min(IntPtr raw, bool enabled);

		public bool HardMin { 
			get {
				bool raw_ret = gst_audio_encoder_get_hard_min(Handle);
				bool ret = raw_ret;
				return ret;
			}
			set {
				gst_audio_encoder_set_hard_min(Handle, value);
			}
		}

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_get_latency(IntPtr raw, out ulong min, out ulong max);

		public void GetLatency(out ulong min, out ulong max) {
			gst_audio_encoder_get_latency(Handle, out min, out max);
		}

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern int gst_audio_encoder_get_lookahead(IntPtr raw);

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_set_lookahead(IntPtr raw, int num);

		public int Lookahead { 
			get {
				int raw_ret = gst_audio_encoder_get_lookahead(Handle);
				int ret = raw_ret;
				return ret;
			}
			set {
				gst_audio_encoder_set_lookahead(Handle, value);
			}
		}

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_merge_tags(IntPtr raw, IntPtr tags, int mode);

		public void MergeTags(Gst.TagList tags, Gst.TagMergeMode mode) {
			gst_audio_encoder_merge_tags(Handle, tags == null ? IntPtr.Zero : tags.Handle, (int) mode);
		}

		public void MergeTags(Gst.TagMergeMode mode) {
			MergeTags (null, mode);
		}

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

		public bool Negotiate() {
			bool raw_ret = gst_audio_encoder_negotiate(Handle);
			bool ret = raw_ret;
			return ret;
		}

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern IntPtr gst_audio_encoder_proxy_getcaps(IntPtr raw, IntPtr caps, IntPtr filter);

		public Gst.Caps ProxyGetcaps(Gst.Caps caps, Gst.Caps filter) {
			IntPtr raw_ret = gst_audio_encoder_proxy_getcaps(Handle, caps == null ? IntPtr.Zero : caps.Handle, filter == null ? IntPtr.Zero : filter.Handle);
			Gst.Caps ret = raw_ret == IntPtr.Zero ? null : (Gst.Caps) GLib.Opaque.GetOpaque (raw_ret, typeof (Gst.Caps), true);
			return ret;
		}

		public Gst.Caps ProxyGetcaps() {
			return ProxyGetcaps (null, null);
		}

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_set_allocation_caps(IntPtr raw, IntPtr allocation_caps);

		public Gst.Caps AllocationCaps { 
			set {
				gst_audio_encoder_set_allocation_caps(Handle, value == null ? IntPtr.Zero : value.Handle);
			}
		}

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_set_headers(IntPtr raw, IntPtr headers);

		public GLib.List Headers { 
			set {
				gst_audio_encoder_set_headers(Handle, value == null ? IntPtr.Zero : value.Handle);
			}
		}

		[DllImport("gstaudio-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern void gst_audio_encoder_set_latency(IntPtr raw, ulong min, ulong max);

		public void SetLatency(ulong min, ulong max) {
			gst_audio_encoder_set_latency(Handle, min, max);
		}

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

		public bool SetOutputFormat(Gst.Caps caps) {
			bool raw_ret = gst_audio_encoder_set_output_format(Handle, caps == null ? IntPtr.Zero : caps.Handle);
			bool ret = raw_ret;
			return ret;
		}

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

		public bool DeletePreset(string name) {
			IntPtr native_name = GLib.Marshaller.StringToPtrGStrdup (name);
			bool raw_ret = gst_preset_delete_preset(Handle, native_name);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_name);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_preset_get_meta(IntPtr raw, IntPtr name, IntPtr tag, out IntPtr value);

		public bool GetMeta(string name, string tag, out string value) {
			IntPtr native_name = GLib.Marshaller.StringToPtrGStrdup (name);
			IntPtr native_tag = GLib.Marshaller.StringToPtrGStrdup (tag);
			IntPtr native_value;
			bool raw_ret = gst_preset_get_meta(Handle, native_name, native_tag, out native_value);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_name);
			GLib.Marshaller.Free (native_tag);
			value = GLib.Marshaller.PtrToStringGFree(native_value);
			return ret;
		}

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

		public string[] PresetNames { 
			get {
				IntPtr raw_ret = gst_preset_get_preset_names(Handle);
				string[] ret = GLib.Marshaller.NullTermPtrToStringArray (raw_ret, true);
				return ret;
			}
		}

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

		public string[] PropertyNames { 
			get {
				IntPtr raw_ret = gst_preset_get_property_names(Handle);
				string[] ret = GLib.Marshaller.NullTermPtrToStringArray (raw_ret, true);
				return ret;
			}
		}

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

		public bool IsEditable { 
			get {
				bool raw_ret = gst_preset_is_editable(Handle);
				bool ret = raw_ret;
				return ret;
			}
		}

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

		public bool LoadPreset(string name) {
			IntPtr native_name = GLib.Marshaller.StringToPtrGStrdup (name);
			bool raw_ret = gst_preset_load_preset(Handle, native_name);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_name);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_preset_rename_preset(IntPtr raw, IntPtr old_name, IntPtr new_name);

		public bool RenamePreset(string old_name, string new_name) {
			IntPtr native_old_name = GLib.Marshaller.StringToPtrGStrdup (old_name);
			IntPtr native_new_name = GLib.Marshaller.StringToPtrGStrdup (new_name);
			bool raw_ret = gst_preset_rename_preset(Handle, native_old_name, native_new_name);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_old_name);
			GLib.Marshaller.Free (native_new_name);
			return ret;
		}

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

		public bool SavePreset(string name) {
			IntPtr native_name = GLib.Marshaller.StringToPtrGStrdup (name);
			bool raw_ret = gst_preset_save_preset(Handle, native_name);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_name);
			return ret;
		}

		[DllImport("gstreamer-1.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
		static extern bool gst_preset_set_meta(IntPtr raw, IntPtr name, IntPtr tag, IntPtr value);

		public bool SetMeta(string name, string tag, string value) {
			IntPtr native_name = GLib.Marshaller.StringToPtrGStrdup (name);
			IntPtr native_tag = GLib.Marshaller.StringToPtrGStrdup (tag);
			IntPtr native_value = GLib.Marshaller.StringToPtrGStrdup (value);
			bool raw_ret = gst_preset_set_meta(Handle, native_name, native_tag, native_value);
			bool ret = raw_ret;
			GLib.Marshaller.Free (native_name);
			GLib.Marshaller.Free (native_tag);
			GLib.Marshaller.Free (native_value);
			return ret;
		}

		public bool SetMeta(string name, string tag) {
			return SetMeta (name, tag, null);
		}


		static AudioEncoder ()
		{
			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 (new List<GLib.AbiField>{ 
						new GLib.AbiField("sinkpad"
							, Gst.Element.abi_info.Fields
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // sinkpad
							, null
							, "srcpad"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("srcpad"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // srcpad
							, "sinkpad"
							, "stream_lock"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("stream_lock"
							, -1
							, (uint) Marshal.SizeOf(typeof(GLib.RecMutex.ABI)) // stream_lock
							, "srcpad"
							, "input_segment"
							, (long) Marshal.OffsetOf(typeof(GstAudioEncoder_stream_lockAlign), "stream_lock")
							, 0
							),
						new GLib.AbiField("input_segment"
							, -1
							, (uint) Marshal.SizeOf(typeof(Gst.Segment)) // input_segment
							, "stream_lock"
							, "output_segment"
							, (long) Marshal.OffsetOf(typeof(GstAudioEncoder_input_segmentAlign), "input_segment")
							, 0
							),
						new GLib.AbiField("output_segment"
							, -1
							, (uint) Marshal.SizeOf(typeof(Gst.Segment)) // output_segment
							, "input_segment"
							, "priv"
							, (long) Marshal.OffsetOf(typeof(GstAudioEncoder_output_segmentAlign), "output_segment")
							, 0
							),
						new GLib.AbiField("priv"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) // priv
							, "output_segment"
							, "_gst_reserved"
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
						new GLib.AbiField("_gst_reserved"
							, -1
							, (uint) Marshal.SizeOf(typeof(IntPtr)) * 20 // _gst_reserved
							, "priv"
							, null
							, (uint) Marshal.SizeOf(typeof(IntPtr))
							, 0
							),
					});

				return _abi_info;
			}
		}

		[StructLayout(LayoutKind.Sequential)]
		public struct GstAudioEncoder_stream_lockAlign
		{
			sbyte f1;
			private GLib.RecMutex.ABI stream_lock;
		}

		[StructLayout(LayoutKind.Sequential)]
		public struct GstAudioEncoder_input_segmentAlign
		{
			sbyte f1;
			private Gst.Segment input_segment;
		}

		[StructLayout(LayoutKind.Sequential)]
		public struct GstAudioEncoder_output_segmentAlign
		{
			sbyte f1;
			private Gst.Segment output_segment;
		}


		// End of the ABI representation.

#endregion
	}
}
