Пример #1
0
 /// <summary>
 /// Verbindet zwei Filter. Es wird erwartet, dass jeweils ein einziger Ein-/Ausgang existiert.
 /// </summary>
 /// <param name="from">Der Filter, der die Daten produziert.</param>
 /// <param name="to">Der Filter, der die Daten entgegennimmt.</param>
 private void Connect(TypedComIdentity <IBaseFilter> from, TypedComIdentity <IBaseFilter> to)
 {
     // Attach to pins
     using (var fromPin = from.GetSinglePin(PinDirection.Output))
         using (var toPin = to.GetSinglePin(PinDirection.Input))
             ((IGraphBuilder)m_Graph).Connect(fromPin.Interface, toPin.Interface);
 }
Пример #2
0
        /// <summary>
        /// Erzeugt einen neuen Filter.
        /// </summary>
        /// <param name="name">Der Name des Filters.</param>
        /// <param name="filter">Der bereits geladene Filter.</param>
        /// <returns>Die COM Schnittstelle des neuen Filters.</returns>
        /// <exception cref="ArgumentNullException">Es wurde kein Filter angegeben.</exception>
        private void AddFilter(string name, TypedComIdentity <IBaseFilter> filter)
        {
            // Validate
            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }

            // Process
            ((IGraphBuilder)m_Graph).AddFilter(filter.Interface, name);
        }
Пример #3
0
        /// <summary>
        /// Beendet den Graphen und gibt alle damit verbundenen Ressourcen frei.
        /// </summary>
        public void Destroy()
        {
            // Disable decryption callback
            Interlocked.Exchange(ref m_PMTSink, null);

            // Pipelines
            DecryptionPipeline.Terminate();
            SignalPipeline.Terminate();
            TunePipeline.Terminate();

            // External registration
            using (m_ExternalRegistration)
                m_ExternalRegistration = null;

            // Extra filters
            var additionalFilters = AdditionalFilters.ToArray();

            // Reset
            AdditionalFilters.Clear();

            // Filter
            foreach (var additionalFilter in additionalFilters)
            {
                if (additionalFilter != null)
                {
                    additionalFilter.Dispose();
                }
            }
            using (m_TIF)
                m_TIF = null;
            using (TransportStreamAnalyser)
                TransportStreamAnalyser = null;
            using (CaptureFilter)
                CaptureFilter = null;
            using (TunerFilter)
                TunerFilter = null;
            using (NetworkProvider)
                NetworkProvider = null;

            // The graph itself
            if (m_Graph != null)
            {
                try
                {
                    // Done with it
                    m_Graph.Stop();
                }
                catch (Exception e)
                {
                    // For now we ignore all errors during shutdown
                    Trace.WriteLine(e.Message);
                }
            }
Пример #4
0
        /// <summary>
        /// Erzeugt einen Graphen und startet ihn.
        /// </summary>
        /// <param name="location">Der Ursprung, über den die Quellgruppe empfangen wird.</param>
        /// <param name="group">Die gewünschte Quellgruppe.</param>
        /// <exception cref="ArgumentException">Es wurden nicht alle Parameter gesetzt.</exception>
        public void Create(GroupLocation location, SourceGroup group)
        {
            // Get rid of it
            Destroy();

            // Create new graph builder
            var graph = Activator.CreateInstance(Type.GetTypeFromCLSID(BDAEnvironment.GraphBuilderClassIdentifier));

            try
            {
                // Convert interface
                m_Graph = (IMediaFilter)graph;
            }
            catch
            {
                // Cleanup
                BDAEnvironment.Release(ref graph);

                // Forward
                throw;
            }

            // See if we should register the graph
            m_ExternalRegistration = BDASettings.RegisterBDAGRaph(m_Graph, false);

            // Attach to alternate interface
            var builder = (IGraphBuilder)m_Graph;

            // Check log
            var logFile = BDASettings.BDALogPath;

            if (logFile != null)
            {
                // Open path
                m_LogFile = new FileStream(logFile.FullName, FileMode.Create, FileAccess.Write, FileShare.Read);

                // Enable logging on graph builder
                builder.SetLogFile(m_LogFile.SafeFileHandle);
            }

            // Start with network provider
            NetworkProvider = AddFilter("Network Provider", BDAEnvironment.GetNetworkProviderMoniker(DVBType));

            // Initialize provider
            Tune(location, group);

            // Always create the tuner
            if (TunerInformation != null)
            {
                TunerFilter = AddFilter("Tuner", TunerInformation);
            }
            else
            {
                throw new ArgumentException(Properties.Resources.Exception_MissingTuner, "Tuner");
            }

            // Optionally create capture
            if (CaptureInformation != null)
            {
                CaptureFilter = AddFilter("Capture", CaptureInformation);
            }

            // Add additional filter
            foreach (var additionalFilter in AdditionalFilterInformations)
            {
                if (additionalFilter == null)
                {
                    throw new ArgumentNullException("AdditionalFilters");
                }
                else
                {
                    AdditionalFilters.Add(AddFilter(additionalFilter.DisplayName, additionalFilter));
                }
            }

            // Connect network provider to streaming instance
            Connect(NetworkProvider, CaptureFilter ?? TunerFilter);

            // Initialize provider
            Tune(location, group);

            // Create the primary filter and add it
            AddFilter("TS", TransportStreamAnalyser = new InputFilter());

            // Connect device output for analysis
            Connect(CaptureFilter ?? TunerFilter, TransportStreamAnalyser);

            // Create the demultiplexer - needed to keep the infrastructure alive
            using (var demux = AddFilter("TIF", BDAEnvironment.MicrosoftDemultiplexerMoniker))
            {
                // Connect to the dedicated pin of our analyser
                TransportStreamAnalyser.DataManager.TIFConnector.Connect(demux, BDAEnvironment.TransportStreamMediaType1);

                // Pins to remove
                var remove = new List <string>();

                // Prepare the demultiplexer pins
                demux.InspectAllPins(pin =>
                {
                    // See if this is the SI pin
                    bool isSectionPin = false;
                    pin.InspectAllMediaTypes(type =>
                    {
                        // Check major
                        if (!type.MajorType.Equals(BDAEnvironment.DataFormatTypeSections))
                        {
                            return(true);
                        }

                        // Check minor
                        isSectionPin = type.SubType.Equals(BDAEnvironment.DataFormatSubtypeSI);

                        // Report
                        return(!isSectionPin);
                    });

                    // Check the mode
                    if (isSectionPin)
                    {
                        // Connect
                        using (var comPin = ComIdentity.Create(pin))
                            builder.Render(comPin.Interface);

                        // Load connection data
                        IntPtr tifIn = IntPtr.Zero;
                        if (pin.ConnectedTo(ref tifIn) < 0)
                        {
                            throw new InvalidOperationException(Properties.Resources.Exception_TIF);
                        }

                        // Reconstruct
                        var tifPin = Marshal.GetObjectForIUnknown(tifIn);
                        try
                        {
                            // Request pin context
                            var info = new PinInfo();
                            ((IPin)tifPin).QueryPinInfo(ref info);

                            // Request from pin
                            m_TIF = info.GetAndDisposeFilter();
                        }
                        finally
                        {
                            // Cleanup
                            BDAEnvironment.Release(ref tifPin);
                        }
                    }
                    else if (pin.QueryDirection() == PinDirection.Output)
                    {
                        // Prepare to kill
                        remove.Add(pin.QueryId());
                    }
                });

                // Prepare to remove all unconnected pins
                if (remove.Count > 0)
                {
                    using (var demuxInstance = demux.MarshalToManaged())
                    {
                        // Change type
                        var mpeg2 = (IMpeg2Demultiplexer)demuxInstance.Object;

                        // Remove all
                        foreach (var id in remove)
                        {
                            mpeg2.DeleteOutputPin(id);
                        }
                    }
                }
            }

            // Install the PMT watchdog
            TransportStreamAnalyser.DataManager.TSParser.PMTFound += ProcessPMT;
        }