/// <summary> /// Attaches a pipeline/bin to the audio player tee, optionally using pad blocking /// </summary> /// <param name="bin"> /// A <see cref="Bin"/> to attach to the player tee /// </param> /// <param name="use_pad_block"> /// A <see cref="System.Boolean"/> indicating whether to use pad blocking or not /// </param> /// <returns> /// A <see cref="System.Boolean"/> -- always true /// </returns> public bool AddBin(Bin bin, bool use_pad_block) { Bin[] user_bins = new Bin[2] { new Bin (this.ToIntPtr ()), bin }; GCHandle gch = GCHandle.Alloc (user_bins); IntPtr user_data = GCHandle.ToIntPtr (gch); Pad fixture_pad = this.GetStaticPad ("sink"); Pad block_pad = fixture_pad.GetPeer (); fixture_pad.UnRef (); if (use_pad_block) { ulong blocking_probe = block_pad.AddProbe (PadProbeType.GST_PAD_PROBE_TYPE_BLOCK, ReallyAddBinBlocked, user_data, null); Hyena.Log.DebugFormat ("[Streamrecorder.PlayerAudioTee]<AddBin> blockin pad {0} to perform an operation ({1})",block_pad.GetPathString (),blocking_probe); } else { Hyena.Log.Debug ("Streamrecorder.PlayerAudioTee]<AddBin> not using blockin pad, calling operation directly"); ReallyAddBinUnblocked (block_pad.ToIntPtr (), IntPtr.Zero, user_data); } block_pad.UnRef (); return true; }
/// <summary> /// Attaches a pipeline/bin to the audio player tee, optionally using pad blocking /// </summary> /// <param name="bin"> /// A <see cref="Bin"/> to attach to the player tee /// </param> /// <param name="use_pad_block"> /// A <see cref="System.Boolean"/> indicating whether to use pad blocking or not /// </param> /// <returns> /// A <see cref="System.Boolean"/> -- always true /// </returns> public bool AddBin (Bin bin, bool use_pad_block) { Bin[] user_bins = new Bin[2] { new Bin (this.ToIntPtr ()), bin }; GCHandle gch = GCHandle.Alloc (user_bins); IntPtr user_data = GCHandle.ToIntPtr (gch); Pad fixture_pad = this.GetStaticPad ("sink"); Pad block_pad = fixture_pad.GetPeer (); fixture_pad.UnRef (); if (use_pad_block) { Hyena.Log.Debug ("[Streamrecorder.PlayerAudioTee]<AddBin> blockin pad " + block_pad.GetPathString () + " to perform an operation"); block_pad.SetBlockedAsync (true, ReallyAddBin, user_data); } else { Hyena.Log.Debug ("Streamrecorder.PlayerAudioTee]<AddBin> not using blockin pad, calling operation directly"); ReallyAddBin (block_pad.ToIntPtr (), false, user_data); } block_pad.UnRef (); return true; }
void IDelayedInitializeService.DelayedInitialize() { if (!has_karaoke) return; playbin = new Bin (ServiceManager.PlayerEngine.ActiveEngine.GetBaseElements ()[0]); audiobin = new Bin (ServiceManager.PlayerEngine.ActiveEngine.GetBaseElements ()[1]); audiotee = new Bin (ServiceManager.PlayerEngine.ActiveEngine.GetBaseElements ()[2]); if (playbin.IsNull ()) { Hyena.Log.Debug ("[Karaoke] Playbin is not yet initialized, cannot start Karaoke Mode"); } audiokaraoke = audiobin.GetByName ("karaoke"); if (audiokaraoke.IsNull ()) { audiokaraoke = ElementFactory.Make ("audiokaraoke","karaoke"); //add audiokaraoke to audiobin audiobin.Add (audiokaraoke); //setting new audiobin sink to audiokaraoke sink GhostPad teepad = new GhostPad (audiobin.GetStaticPad ("sink").ToIntPtr ()); Pad audiokaraokepad = audiokaraoke.GetStaticPad ("sink"); teepad.SetTarget (audiokaraokepad); //link audiokaraoke sink and audiotee sink audiokaraoke.Link (audiotee); } if (!karaoke_enabled) { audiokaraoke.SetFloatProperty ("level", 0); audiokaraoke.SetFloatProperty ("mono-level", 0); } else { audiokaraoke.SetFloatProperty ("level", effect_level); audiokaraoke.SetFloatProperty ("mono-level", effect_level); } }
/// <summary> /// Creates a new recoding pipeline with the best (by user preference) available encoder and attaches it /// to the audiotee /// </summary> /// <returns> /// A <see cref="System.Boolean"/>, true if the pipeline was successfully created, false otherwise. /// </returns> public bool Create() { string bin_description = BuildPipeline (); try { audiotee = new PlayerAudioTee (ServiceManager.PlayerEngine.ActiveEngine.GetBaseElements ()[2]); if (bin_description.Equals ("")) { return false; } encoder_bin = Parse.BinFromDescription (bin_description, true); // Hyena.Log.Debug ("DEBUG bin to string: " + encoder_bin.ToString()); tagger = new TagSetter (encoder_bin.GetByInterface (TagSetter.GetType ())); file_sink = encoder_bin.GetByName ("file_sink").ToFileSink (); file_sink.Location = empty_file; file_sink.SetBooleanProperty ("sync", true); file_sink.SetBooleanProperty ("async", false); OldGLib.Object.GetObject (file_sink.ToIntPtr ()).AddNotification ("allow-overwrite", OnAllowOverwrite); ghost_pad = encoder_bin.GetStaticPad ("sink").ToGhostPad (); outputselector = encoder_bin.GetByName ("sel"); Pad filesinkpad = file_sink.GetStaticPad ("sink"); selector_filepad = filesinkpad.GetPeer (); Element fake_sink = encoder_bin.GetByName ("fake_sink"); Pad fakesinkpad = fake_sink.GetStaticPad ("sink"); selector_fakepad = fakesinkpad.GetPeer (); audiotee.AddBin (encoder_bin, ServiceManager.PlayerEngine.CurrentState == PlayerState.Playing); Hyena.Log.Debug ("[Recorder] Recorder attached"); } catch (Exception e) { Hyena.Log.InformationFormat ("[Streamrecorder] An exception occurred during pipeline construction: {0}", bin_description); Hyena.Log.Debug (e.Message); Hyena.Log.Debug (e.StackTrace); return false; } return true; }
/// <summary> /// Creates a new recoding pipeline with the best (by user preference) available encoder /// </summary> /// <returns> /// A <see cref="System.Boolean"/>, true if the pipeline was successfully created, false otherwise. /// </returns> public bool Create() { string bin_description = BuildPipeline (); try { audiotee = new PlayerAudioTee (ServiceManager.PlayerEngine.ActiveEngine.GetBaseElements ()[2]); if (bin_description.Equals ("")) { return false; } encoder_bin = Parse.BinFromDescription (bin_description, true); tagger = new TagSetter (encoder_bin.GetByInterface (TagSetter.GetType ())); file_sink = encoder_bin.GetByName ("file_sink").ToFileSink (); file_sink.Location = output_file + file_extension; file_sink.SetBooleanProperty ("sync", true); file_sink.SetBooleanProperty ("async", false); GLib.Object.GetObject (file_sink.ToIntPtr ()).AddNotification ("allow-overwrite", OnAllowOverwrite); ghost_pad = encoder_bin.GetStaticPad ("sink").ToGhostPad (); } catch (Exception e) { Hyena.Log.InformationFormat ("[Streamrecorder] An exception occurred during pipeline construction: {0}", bin_description); Hyena.Log.Debug (e.StackTrace); return false; } return true; }
/// <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> /// Removes a pipeline/bin from the audio player tee, optionally using pad blocking /// </summary> /// <param name="bin"> /// The <see cref="Bin"/> to remove /// </param> /// <param name="use_pad_block"> /// A <see cref="System.Boolean"/> indicating whether to use pad blocking or not /// </param> /// <returns> /// A <see cref="System.Boolean"/> -- always true /// </returns> public bool RemoveBin (Bin bin, bool use_pad_block) { IntPtr user_data = bin.ToIntPtr (); Pad fixture_pad = this.GetStaticPad ("sink"); Pad block_pad = fixture_pad.GetPeer (); fixture_pad.UnRef (); if (use_pad_block) { Hyena.Log.Debug ("[Streamrecorder.PlayerAudioTee]<RemoveBin> blockin pad " + block_pad.GetPathString () + " to perform an operation"); block_pad.SetBlockedAsync (true, ReallyRemoveBin, user_data); } else { Hyena.Log.Debug ("[Streamrecorder.PlayerAudioTee]<RemoveBin> not using blockin pad, calling operation directly"); ReallyRemoveBin (block_pad.ToIntPtr (), false, user_data); } block_pad.UnRef (); return true; }
/// <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 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; }