/// <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); } }
/// <summary> /// Gibt alle internen Strukturen frei. /// </summary> private void DestroyGraph() { // Get rid of clock DisposeClock(); // Try stop and delete all filters if (null != m_Graph) try { // Stop self GraphAsFilter.Stop(); } catch { } // Filters first foreach (var filter in m_Filters.Values) filter.Dispose(); // Clear list m_Filters.Clear(); // Forward using (m_Register) m_Register = null; // Must cleanup COM references BDAEnvironment.Release( ref m_Graph ); // Must cleanup file using (m_LogFile) m_LogFile = null; // Clear helpers and reset flags m_VideoWindowCreated = false; m_VideoPID = 0; m_AudioPID = 0; // TS Filter using (InjectorFilter) InjectorFilter = null; }
/// <summary> /// Initialisiert die Filterstruktur. /// </summary> public void CreateGraph() { // Cleanup DestroyGraph(); // Check log var logFile = BDASettings.BDALogPath; if (logFile != null) m_LogFile = new FileStream( logFile.FullName, FileMode.Create, FileAccess.Write, FileShare.Read ); // Create new graph builder m_Graph = (IGraphBuilder) Activator.CreateInstance( Type.GetTypeFromCLSID( BDAEnvironment.GraphBuilderClassIdentifier ) ); // Enable logging if (m_LogFile != null) m_Graph.SetLogFile( m_LogFile.SafeFileHandle ); // See if we should register the graph m_Register = BDASettings.RegisterBDAGRaph( DirectShowObject, false ); // Create filter InjectorFilter = new TSFilter( this ); try { // Check for statistics InjectorFilter.EnableStatistics = BDASettings.GenerateTSStatistics; // Register in graph AddFilter( Filter_Injector, InjectorFilter ); } catch { // Cleanup InjectorFilter.Dispose(); // Forward throw; } }
/// <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; }
/// <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 ); } finally { // Get rid of it BDAEnvironment.Release( ref m_Graph ); } // Log file using (var logFile = m_LogFile) { // Forget m_LogFile = null; // Make sure that we have written it all out if (logFile != null) logFile.Flush(); } }
/// <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; }