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