// --------------------- Private Methods ----------------------- /// <summary> /// Create a new filter graph and add filters (devices, compressors, /// misc), but leave the filters unconnected. Call renderGraph() /// to connect the filters. /// </summary> protected void createGraph() { Guid cat; Guid med; int hr; // Ensure required properties are set if ( videoDevice == null && audioDevice == null ) throw new ArgumentException( "The video and/or audio device have not been set. Please set one or both to valid capture devices.\n" ); // Skip if we are already created if ( (int)graphState < (int)GraphState.Created ) { // Garbage collect, ensure that previous filters are released GC.Collect(); // Make a new filter graph #if DSHOWNET // Make a new filter graph graphBuilder = (IGraphBuilder)Activator.CreateInstance(Type.GetTypeFromCLSID(Clsid.FilterGraph, true)); // Get the Capture Graph Builder Guid clsid = Clsid.CaptureGraphBuilder2; Guid riid = typeof(ICaptureGraphBuilder2).GUID; captureGraphBuilder = (ICaptureGraphBuilder2)DsBugWO.CreateDsInstance(ref clsid, ref riid); #else FilterGraph graph = new FilterGraph(); graphBuilder = (IGraphBuilder)graph; // Get the Capture Graph Builder captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); #endif // Link the CaptureGraphBuilder to the filter graph hr = captureGraphBuilder.SetFiltergraph(graphBuilder); if (hr < 0) Marshal.ThrowExceptionForHR(hr); // Add the graph to the Running Object Table so it can be // viewed with GraphEdit #if DEBUG #if DSHOWNET DsROT.AddGraphToRot(graphBuilder, out rotCookie); #else rotCookie = new DsROTEntry(graphBuilder); #endif #endif // Get the video device and add it to the filter graph if ( VideoDevice != null ) { videoDeviceFilter = (IBaseFilter) Marshal.BindToMoniker( VideoDevice.MonikerString ); hr = graphBuilder.AddFilter( videoDeviceFilter, "Video Capture Device" ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); } // Get the audio device and add it to the filter graph if ( AudioDevice != null ) { audioDeviceFilter = (IBaseFilter) Marshal.BindToMoniker( AudioDevice.MonikerString ); hr = graphBuilder.AddFilter( audioDeviceFilter, "Audio Capture Device" ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); } // Get the video compressor and add it to the filter graph if ( VideoCompressor != null ) { videoCompressorFilter = (IBaseFilter) Marshal.BindToMoniker( VideoCompressor.MonikerString ); hr = graphBuilder.AddFilter( videoCompressorFilter, "Video Compressor" ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); } // Get the audio compressor and add it to the filter graph if ( AudioCompressor != null ) { audioCompressorFilter = (IBaseFilter) Marshal.BindToMoniker( AudioCompressor.MonikerString ); hr = graphBuilder.AddFilter( audioCompressorFilter, "Audio Compressor" ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); } // Retrieve the stream control interface for the video device // FindInterface will also add any required filters // (WDM devices in particular may need additional // upstream filters to function). // Try looking for an interleaved media type object o; cat = PinCategory.Capture; med = MediaType.Interleaved; Guid iid = typeof(IAMStreamConfig).GUID; #if DSHOWNET hr = captureGraphBuilder.FindInterface( ref cat, ref med, videoDeviceFilter, ref iid, out o); #else hr = captureGraphBuilder.FindInterface( DsGuid.FromGuid(cat), DsGuid.FromGuid(med), videoDeviceFilter, DsGuid.FromGuid(iid), out o ); #endif if ( hr != 0 ) { // If not found, try looking for a video media type med = MediaType.Video; #if DSHOWNET hr = captureGraphBuilder.FindInterface( ref cat, ref med, videoDeviceFilter, ref iid, out o); #else hr = captureGraphBuilder.FindInterface( DsGuid.FromGuid(cat), DsGuid.FromGuid(med), videoDeviceFilter, DsGuid.FromGuid(iid), out o ); #endif if ( hr != 0 ) o = null; } videoStreamConfig = o as IAMStreamConfig; // #if NEWCODE // Start of new Brian's Low code // Retrieve the stream control interface for the video device // FindInterface will also add any required filters // (WDM devices in particular may need additional // upstream filters to function). // Try looking for an interleaved media type o = null; cat = PinCategory.Preview; med = MediaType.Interleaved; iid = typeof(IAMStreamConfig).GUID; #if DSHOWNET hr = captureGraphBuilder.FindInterface( ref cat, ref med, videoDeviceFilter, ref iid, out o); #else hr = captureGraphBuilder.FindInterface( DsGuid.FromGuid(cat), DsGuid.FromGuid(med), videoDeviceFilter, DsGuid.FromGuid(iid), out o ); #endif if ( hr != 0 ) { // If not found, try looking for a video media type med = MediaType.Video; #if DSHOWNET hr = captureGraphBuilder.FindInterface( ref cat, ref med, videoDeviceFilter, ref iid, out o); #else hr = captureGraphBuilder.FindInterface( DsGuid.FromGuid(cat), DsGuid.FromGuid(med), videoDeviceFilter, DsGuid.FromGuid(iid), out o ); #endif if ( hr != 0 ) o = null; } this.previewStreamConfig = o as IAMStreamConfig; // End of new Brian's Low code if( (this.videoStreamConfig != null)|| (this.previewStreamConfig != null) ) { this.dxUtils = new DxUtils(); bool result = this.dxUtils.InitDxUtils(this.videoDeviceFilter); if((!result)&&(!this.dxUtils.FindMediaData(this.videoStreamConfig))) { this.dxUtils.Dispose(); this.dxUtils = null; } } // #endif // Retrieve the stream control interface for the audio device o = null; cat = PinCategory.Capture; med = MediaType.Audio ; iid = typeof(IAMStreamConfig).GUID; if( (this.AudioViaPci)&& (audioDeviceFilter == null)&&(videoDeviceFilter != null) ) { hr = captureGraphBuilder.FindInterface( #if DSHOWNET ref cat, ref med, videoDeviceFilter, ref iid, out o ); #else DsGuid.FromGuid(cat), DsGuid.FromGuid(med), videoDeviceFilter, DsGuid.FromGuid(iid), out o); #endif } else { #if DSHOWNET hr = captureGraphBuilder.FindInterface( ref cat, ref med, audioDeviceFilter, ref iid, out o); #else hr = captureGraphBuilder.FindInterface( DsGuid.FromGuid(cat), DsGuid.FromGuid(med), audioDeviceFilter, DsGuid.FromGuid(iid), out o ); #endif } if (hr != 0) o = null; audioStreamConfig = o as IAMStreamConfig; // Retreive the media control interface (for starting/stopping graph) mediaControl = (IMediaControl) graphBuilder; // Reload any video crossbars if ( videoSources != null ) videoSources.Dispose(); videoSources = null; // Reload any audio crossbars if ( audioSources != null ) audioSources.Dispose(); audioSources = null; // Reload any property pages exposed by filters this.PropertyPages = null; // Reload capabilities of video device videoCaps = null; previewCaps = null; // Reload capabilities of video device audioCaps = null; // Retrieve TV Tuner if available o = null; cat = PinCategory.Capture; med = MediaType.Interleaved; iid = typeof(IAMTVTuner).GUID; #if DSHOWNET hr = captureGraphBuilder.FindInterface( ref cat, ref med, videoDeviceFilter, ref iid, out o); #else hr = captureGraphBuilder.FindInterface( DsGuid.FromGuid(cat), DsGuid.FromGuid(med), videoDeviceFilter, DsGuid.FromGuid(iid), out o ); #endif if ( hr != 0 ) { med = MediaType.Video ; #if DSHOWNET hr = captureGraphBuilder.FindInterface( ref cat, ref med, videoDeviceFilter, ref iid, out o); #else hr = captureGraphBuilder.FindInterface( DsGuid.FromGuid(cat), DsGuid.FromGuid(med), videoDeviceFilter, DsGuid.FromGuid(iid), out o ); #endif if ( hr != 0 ) o = null; } IAMTVTuner t = o as IAMTVTuner; if ( t != null ) { tuner = new Tuner(t); // Do not forget to set proper country code (Netherlands is 31) } // No check on TV Audio needed, it will show up in the // PropertyPages when it is available // Code for finding the TV audio interface o = null; cat = PinCategory.Capture; med = MediaType.Interleaved; iid = typeof(IAMTVAudio).GUID; hr = captureGraphBuilder.FindInterface( #if DSHOWNET ref cat, ref med, videoDeviceFilter, ref iid, out o); #else cat, med, videoDeviceFilter, iid, out o); #endif if ( hr != 0 ) { med = MediaType.Video; #if DSHOWNET hr = captureGraphBuilder.FindInterface( ref cat, ref med, videoDeviceFilter, ref iid, out o); #else hr = captureGraphBuilder.FindInterface( cat, med, videoDeviceFilter, iid, out o); #endif if ( hr != 0 ) { o = null; } } if((o != null)&&(tuner != null)) { IAMTVAudio a = o as IAMTVAudio; TvAudio = a; #if DEBUG Debug.WriteLine("FindInterface tuner.TvAudio"); #endif // DEBUG } /* // ----------- VMR 9 ------------------- //## check out samples\inc\vmrutil.h :: RenderFileToVMR9 IBaseFilter vmr = null; if ( ( VideoDevice != null ) && ( previewWindow != null ) ) { vmr = (IBaseFilter) Activator.CreateInstance( Type.GetTypeFromCLSID( Clsid.VideoMixingRenderer9, true ) ); hr = graphBuilder.AddFilter( vmr, "VMR" ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); IVMRFilterConfig9 vmrFilterConfig = (IVMRFilterConfig9) vmr; hr = vmrFilterConfig.SetRenderingMode( VMRMode9.Windowless ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); IVMRWindowlessControl9 vmrWindowsless = (IVMRWindowlessControl9) vmr; hr = vmrWindowsless.SetVideoClippingWindow( previewWindow.Handle ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); } //------------------------------------------- // ---------- SmartTee --------------------- IBaseFilter smartTeeFilter = (IBaseFilter) Activator.CreateInstance( Type.GetTypeFromCLSID( Clsid.SmartTee, true ) ); hr = graphBuilder.AddFilter( smartTeeFilter, "Video Smart Tee" ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); // Video -> SmartTee cat = PinCategory.Capture; med = MediaType.Video; hr = captureGraphBuilder.RenderStream( DsGuid.FromGuid(cat), DsGuid.FromGuid(med), videoDeviceFilter, null, smartTeeFilter ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); // smarttee -> mux cat = PinCategory.Capture; med = MediaType.Video; hr = captureGraphBuilder.RenderStream( DsGuid.FromGuid(cat), DsGuid.FromGuid(med), smartTeeFilter, null, muxFilter ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); // smarttee -> vmr cat = PinCategory.Preview; med = MediaType.Video; hr = captureGraphBuilder.RenderStream( DsGuid.FromGuid(cat), DsGuid.FromGuid(med), smartTeeFilter, null, vmr ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); // ------------------------------------- */ // Update the state now that we are done graphState = GraphState.Created; } }
/// <summary> /// Completely tear down a filter graph and /// release all associated resources. /// </summary> protected void destroyGraph() { // Derender the graph (This will stop the graph // and release preview window. It also destroys // half of the graph which is unnecessary but // harmless here.) (ignore errors) try{ derenderGraph(); } catch {} // Update the state after derender because it // depends on correct status. But we also want to // update the state as early as possible in case // of error. graphState = GraphState.Null; isCaptureRendered = false; isPreviewRendered = false; // Remove graph from the ROT #if DSHOWNET if ( rotCookie != 0 ) { DsROT.RemoveGraphFromRot( ref rotCookie ); rotCookie = 0; } #else if (rotCookie != null) { rotCookie.Dispose(); rotCookie = null; } #endif // Remove filters from the graph // This should be unnecessary but the Nvidia WDM // video driver cannot be used by this application // again unless we remove it. Ideally, we should // simply enumerate all the filters in the graph // and remove them. (ignore errors) if ( muxFilter != null ) graphBuilder.RemoveFilter( muxFilter ); if ( videoCompressorFilter != null ) graphBuilder.RemoveFilter( videoCompressorFilter ); if ( audioCompressorFilter != null ) graphBuilder.RemoveFilter( audioCompressorFilter ); if ( videoDeviceFilter != null ) graphBuilder.RemoveFilter( videoDeviceFilter ); if ( audioDeviceFilter != null ) graphBuilder.RemoveFilter( audioDeviceFilter ); if(this.videoRendererFilter != null) { this.graphBuilder.RemoveFilter(this.videoRendererFilter); } // Clean up properties if ( videoSources != null ) videoSources.Dispose(); videoSources = null; if ( audioSources != null ) audioSources.Dispose(); audioSources = null; this.PropertyPages = null; // Disposal done within PropertyPages if ( tuner != null ) tuner.Dispose(); tuner = null; // #if NEWCODE if(this.tvAudio != null) { Marshal.ReleaseComObject(this.tvAudio); tvAudio = null; } if(this.dxUtils != null) { this.dxUtils.Dispose(); this.dxUtils = null; } // #endif // Cleanup if ( graphBuilder != null ) Marshal.ReleaseComObject( graphBuilder ); graphBuilder = null; if ( captureGraphBuilder != null ) Marshal.ReleaseComObject( captureGraphBuilder ); captureGraphBuilder = null; if ( muxFilter != null ) Marshal.ReleaseComObject( muxFilter ); muxFilter = null; if ( fileWriterFilter != null ) Marshal.ReleaseComObject( fileWriterFilter ); fileWriterFilter = null; if ( videoDeviceFilter != null ) Marshal.ReleaseComObject( videoDeviceFilter ); videoDeviceFilter = null; if ( audioDeviceFilter != null ) Marshal.ReleaseComObject( audioDeviceFilter ); audioDeviceFilter = null; if ( videoCompressorFilter != null ) Marshal.ReleaseComObject( videoCompressorFilter ); videoCompressorFilter = null; if ( audioCompressorFilter != null ) Marshal.ReleaseComObject( audioCompressorFilter ); audioCompressorFilter = null; // #if NEWCODE this.DisposeSampleGrabber(); // #endif if(this.videoRendererFilter != null) { Marshal.ReleaseComObject(this.videoRendererFilter); this.videoRendererFilter = null; } // These are copies of graphBuilder mediaControl = null; videoWindow = null; // For unmanaged objects we haven't released explicitly GC.Collect(); }
// --------------------- Private Methods ----------------------- /// <summary> /// Create a new filter graph and add filters (devices, compressors, /// misc), but leave the filters unconnected. Call renderGraph() /// to connect the filters. /// </summary> protected void createGraph() { Guid cat; Guid med; int hr; Type comType = null; object comObj = null; // Ensure required properties are set if ( videoDevice == null && audioDevice == null ) throw new ArgumentException( "The video and/or audio device have not been set. Please set one or both to valid capture devices.\n" ); // Skip if we are already created if ( (int)graphState < (int)GraphState.Created ) { // Garbage collect, ensure that previous filters are released GC.Collect(); // Make a new filter graph graphBuilder = (IGraphBuilder) Activator.CreateInstance( Type.GetTypeFromCLSID( Clsid.FilterGraph, true ) ); // Get the Capture Graph Builder Guid clsid = Clsid.CaptureGraphBuilder2; Guid riid = typeof(ICaptureGraphBuilder2).GUID; captureGraphBuilder = (ICaptureGraphBuilder2) DsBugWO.CreateDsInstance( ref clsid, ref riid ); // sampGrabber, ISampleGrabber to capture frames comType=Type.GetTypeFromCLSID( Clsid.SampleGrabber, true ); if(comType==null) throw new NotImplementedException (@"DirectShow SampleGrabber not installed/registered"); comObj=Activator.CreateInstance( comType ); sampGrabber = (ISampleGrabber) comObj; comObj = null; // Link the CaptureGraphBuilder to the filter graph hr = captureGraphBuilder.SetFiltergraph( graphBuilder ); //if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); // Begin set up of SampGrabber <<<<<<---------------------------------------------------- AMMediaType media = new AMMediaType(); media.majorType= MediaType.Video; media.subType = MediaSubType.RGB24; media.formatType = FormatType.VideoInfo; hr = sampGrabber.SetMediaType( media ); //if( hr<0 ) Marshal.ThrowExceptionForHR( hr ); // Finish set up of SampGrabber <<<<<<---------------------------------------------------- // Add the graph to the Running Object Table so it can be // viewed with GraphEdit #if DEBUG DsROT.AddGraphToRot( graphBuilder, out rotCookie ); #endif // Get the video device and add it to the filter graph if ( VideoDevice != null ) { videoDeviceFilter = (IBaseFilter) Marshal.BindToMoniker( VideoDevice.MonikerString ); hr = graphBuilder.AddFilter( videoDeviceFilter, "Video Capture Device" ); //if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); // Add SampGrabber Filter <<<<<<---------------------------------------------------- mediaEvt = (IMediaEventEx) graphBuilder; baseGrabFlt = (IBaseFilter) sampGrabber; hr = graphBuilder.AddFilter( baseGrabFlt, "DS.NET Grabber" ); //if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); } // Get the audio device and add it to the filter graph if ( AudioDevice != null ) { audioDeviceFilter = (IBaseFilter) Marshal.BindToMoniker( AudioDevice.MonikerString ); hr = graphBuilder.AddFilter( audioDeviceFilter, "Audio Capture Device" ); //if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); } // Get the video compressor and add it to the filter graph if ( VideoCompressor != null ) { videoCompressorFilter = (IBaseFilter) Marshal.BindToMoniker( VideoCompressor.MonikerString ); hr = graphBuilder.AddFilter( videoCompressorFilter, "Video Compressor" ); //if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); } // Get the audio compressor and add it to the filter graph if ( AudioCompressor != null ) { audioCompressorFilter = (IBaseFilter) Marshal.BindToMoniker( AudioCompressor.MonikerString ); hr = graphBuilder.AddFilter( audioCompressorFilter, "Audio Compressor" ); //if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); } // Retrieve the stream control interface for the video device // FindInterface will also add any required filters // (WDM devices in particular may need additional // upstream filters to function). // Try looking for an interleaved media type object o; cat = PinCategory.Capture; med = MediaType.Interleaved; Guid iid = typeof(IAMStreamConfig).GUID; hr = captureGraphBuilder.FindInterface( ref cat, ref med, videoDeviceFilter, ref iid, out o ); if ( hr != 0 ) { // If not found, try looking for a video media type med = MediaType.Video; hr = captureGraphBuilder.FindInterface( ref cat, ref med, videoDeviceFilter, ref iid, out o ); if ( hr != 0 ) o = null; } videoStreamConfig = o as IAMStreamConfig; // Retrieve the stream control interface for the audio device o = null; cat = PinCategory.Capture; med = MediaType.Audio ; iid = typeof(IAMStreamConfig).GUID; hr = captureGraphBuilder.FindInterface( ref cat, ref med, audioDeviceFilter, ref iid, out o ); if ( hr != 0 ) o = null; audioStreamConfig = o as IAMStreamConfig; // Retreive the media control interface (for starting/stopping graph) mediaControl = (IMediaControl) graphBuilder; // Reload any video crossbars if ( videoSources != null ) videoSources.Dispose(); videoSources = null; // Reload any audio crossbars if ( audioSources != null ) audioSources.Dispose(); audioSources = null; // Reload any property pages exposed by filters if ( propertyPages != null ) propertyPages.Dispose(); propertyPages = null; // Reload capabilities of video device videoCaps = null; // Reload capabilities of video device audioCaps = null; // Retrieve TV Tuner if available o = null; cat = PinCategory.Capture; med = MediaType.Interleaved; iid = typeof(IAMTVTuner).GUID; hr = captureGraphBuilder.FindInterface( ref cat, ref med, videoDeviceFilter, ref iid, out o ); if ( hr != 0 ) { med = MediaType.Video ; hr = captureGraphBuilder.FindInterface( ref cat, ref med, videoDeviceFilter, ref iid, out o ); if ( hr != 0 ) o = null; } IAMTVTuner t = o as IAMTVTuner; if ( t != null ) tuner = new Tuner( t ); /* // ----------- VMR 9 ------------------- //## check out samples\inc\vmrutil.h :: RenderFileToVMR9 IBaseFilter vmr = null; if ( ( VideoDevice != null ) && ( previewWindow != null ) ) { vmr = (IBaseFilter) Activator.CreateInstance( Type.GetTypeFromCLSID( Clsid.VideoMixingRenderer9, true ) ); hr = graphBuilder.AddFilter( vmr, "VMR" ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); IVMRFilterConfig9 vmrFilterConfig = (IVMRFilterConfig9) vmr; hr = vmrFilterConfig.SetRenderingMode( VMRMode9.Windowless ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); IVMRWindowlessControl9 vmrWindowsless = (IVMRWindowlessControl9) vmr; hr = vmrWindowsless.SetVideoClippingWindow( previewWindow.Handle ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); } //------------------------------------------- // ---------- SmartTee --------------------- IBaseFilter smartTeeFilter = (IBaseFilter) Activator.CreateInstance( Type.GetTypeFromCLSID( Clsid.SmartTee, true ) ); hr = graphBuilder.AddFilter( smartTeeFilter, "Video Smart Tee" ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); // Video -> SmartTee cat = PinCategory.Capture; med = MediaType.Video; hr = captureGraphBuilder.RenderStream( ref cat, ref med, videoDeviceFilter, null, smartTeeFilter ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); // smarttee -> mux cat = PinCategory.Capture; med = MediaType.Video; hr = captureGraphBuilder.RenderStream( ref cat, ref med, smartTeeFilter, null, muxFilter ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); // smarttee -> vmr cat = PinCategory.Preview; med = MediaType.Video; hr = captureGraphBuilder.RenderStream( ref cat, ref med, smartTeeFilter, null, vmr ); if( hr < 0 ) Marshal.ThrowExceptionForHR( hr ); // ------------------------------------- */ // Update the state now that we are done graphState = GraphState.Created; } }