/// <summary> /// Helper function to really attach a bin to the audio player tee /// </summary> /// <param name="pad"> /// A <see cref="IntPtr"/> referencing the pad that may need to be unblocked /// </param> /// <param name="blocked"> /// A <see cref="System.Boolean"/> indicating if the pad is blocked /// </param> /// <param name="user_data"> /// A <see cref="IntPtr"/> containing references to the bin and the audio tee /// </param> private void ReallyAddBin (IntPtr pad, bool blocked, IntPtr user_data) { GCHandle gch = GCHandle.FromIntPtr (user_data); Bin[] user_bins = (Gst.Bin[])gch.Target; Bin fixture = user_bins[0]; Bin element = user_bins[1]; Element queue; Element audioconvert; Bin bin; Bin parent_bin; Pad sink_pad; Pad ghost_pad; GstObject element_parent; element_parent = element.GetParent (); if (element_parent != null && !element_parent.IsNull ()) { Hyena.Log.Debug ("[Streamrecorder.PlayerAudioTee]<ReallyAddBin>element already linked, exiting. assume double function call"); element_parent.UnRef (); return; } /* set up containing bin */ bin = new Bin (); queue = ElementFactory.Make ("queue"); audioconvert = ElementFactory.Make ("audioconvert"); bin.SetBooleanProperty ("async-handling", true); queue.SetIntegerProperty ("max-size-buffers", 10); bin.AddMany (new Element[3] { queue, audioconvert, element }); queue.LinkMany (new Element[2] { audioconvert, element }); sink_pad = queue.GetStaticPad ("sink"); ghost_pad = new GhostPad ("sink", sink_pad); bin.AddPad (ghost_pad); parent_bin = new Bin (fixture.GetParent ().ToIntPtr ()); parent_bin.Add (bin); fixture.Link (bin); attached = true; if (blocked) { Hyena.Log.Debug ("[Streamrecorder.PlayerAudioTee]<ReallyAddBin> unblocking pad after adding tee"); parent_bin.SetState (State.Playing); ghost_pad.Ref (); parent_bin.UnRef (); new Pad (pad).SetBlockedAsync (false, AddRemoveBinDone, ghost_pad.ToIntPtr ()); } else { parent_bin.SetState (State.Paused); ghost_pad.Ref (); parent_bin.UnRef (); AddRemoveBinDone (IntPtr.Zero, false, ghost_pad.ToIntPtr ()); } }
/// <summary> /// Helper function to really remove the bin from the audio player tee /// </summary> /// <param name="pad"> /// A <see cref="IntPtr"/> referencing the pad that may need to be unblocked /// </param> /// <param name="blocked"> /// A <see cref="System.Boolean"/> indicating if the pad is blocked /// </param> /// <param name="user_data"> /// A <see cref="IntPtr"/> containing a reference to the bin /// </param> private void ReallyRemoveBin (IntPtr pad, bool blocked, IntPtr user_data) { Bin element = new Bin (user_data); Bin bin; Bin parent_bin; string element_path = element.GetPathString (); if (!element_path.Contains (":") && element_path.StartsWith ("/0x")) { Hyena.Log.Debug ("[Streamrecorder.PlayerAudioTee]<ReallyRemoveBin> element empty, assume disposed, exiting: " + element_path); return; } bin = new Bin (element.GetParent ().ToIntPtr ()); bin.Ref (); parent_bin = new Bin (bin.GetParent ().ToIntPtr ()); parent_bin.Remove (bin); bin.SetState (State.Null); bin.Remove (element); bin.UnRef (); attached = false; /* if we're supposed to be playing, unblock the sink */ if (blocked) { Hyena.Log.Debug ("[Streamrecorder.PlayerAudioTee]<ReallyRemoveBin> unblocking pad after removing tee"); new Pad (pad).SetBlockedAsync (false, AddRemoveBinDone, IntPtr.Zero); } }
/// <summary> /// Helper function to really remove the bin from the audio player tee /// </summary> /// <param name="pad"> /// A <see cref="IntPtr"/> referencing the pad that may need to be unblocked /// </param> /// <param name="blocked"> /// A <see cref="System.Boolean"/> indicating if the pad is blocked /// </param> /// <param name="user_data"> /// A <see cref="IntPtr"/> containing a reference to the bin /// </param> private PadProbeReturn ReallyRemoveBin(IntPtr pad, IntPtr probe_info, IntPtr user_data, bool blocked) { Bin element = new Bin (user_data); Bin bin; Bin parent_bin; string element_path = element.GetPathString (); if (!element_path.Contains (":") && element_path.StartsWith ("/0x")) { Hyena.Log.Debug ("[Streamrecorder.PlayerAudioTee]<ReallyRemoveBin> element empty, assume disposed, exiting: " + element_path); return PadProbeReturn.GST_PAD_PROBE_OK; } bin = new Bin (element.GetParent ().ToIntPtr ()); bin.Ref (); parent_bin = new Bin (bin.GetParent ().ToIntPtr ()); parent_bin.Remove (bin); bin.SetState (State.Null); bin.Remove (element); bin.UnRef (); attached = false; /* if we're supposed to be playing, unblock the sink */ if (blocked) { Hyena.Log.Debug ("[Streamrecorder.PlayerAudioTee]<ReallyRemoveBin> unblocking pad after removing tee"); // new Pad (pad).AddProbe (PadProbeType.GST_PAD_PROBE_TYPE_BLOCK, AddRemoveBinDone, IntPtr.Zero, null); PadProbeInfo info = (PadProbeInfo) Marshal.PtrToStructure (probe_info, typeof (PadProbeInfo)); new Pad (pad).RemoveProbe (info.id); AddRemoveBinDone (IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); } return PadProbeReturn.GST_PAD_PROBE_OK; }