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 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)BugFixes.InstantiateDirectShow(ref clsid, ref riid); // 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 rotCookie = DsROT.AddGraphToRot(graphBuilder); #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; 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); } // Update the state now that we are done graphState = GraphState.Created; } }
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 (rotCookie != 0) { DsROT.RemoveGraphFromRot(ref rotCookie); rotCookie = 0; } // 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); } // Clean up properties if (videoSources != null) { videoSources.Dispose(); } videoSources = null; if (audioSources != null) { audioSources.Dispose(); } audioSources = null; if (propertyPages != null) { propertyPages.Dispose(); } propertyPages = null; if (tuner != null) { tuner.Dispose(); } tuner = null; // 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; // These are copies of graphBuilder mediaControl = null; videoWindow = null; // For unmanaged objects we haven't released explicitly GC.Collect(); }