/// <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;
        }
예제 #2
0
        /// <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;
        }
예제 #6
0
        /// <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);
            }

        }
예제 #7
0
        /// <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;
        }
예제 #8
0
        /// <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;
        }