Exemplo n.º 1
0
        /// <summary>
        ///  Connects the filters of a previously created graph
        ///  (created by CreateGraph()). Once rendered the graph
        ///  is ready to be used. This method may also destroy
        ///  streams if we have streams we no longer want.
        /// </summary>
        void RenderGraph()
        {
            var didSomething = false;

            // Stop the graph
            _mediaControl?.Stop();

            // Create the graph if needed (group should already be created)
            CreateGraph();

            // Derender the graph if we have a capture or preview stream
            // that we no longer want. We can't derender the capture and
            // preview streams seperately.
            // Notice the second case will leave a capture stream intact
            // even if we no longer want it. This allows the user that is
            // not using the preview to Stop() and Start() without
            // rerendering the graph.
            if (!_wantPreviewRendered && _isPreviewRendered)
            {
                DerenderGraph();
            }

            // Render preview stream (only if necessary)
            if (_wantPreviewRendered && !_isPreviewRendered)
            {
                // Render preview (video -> renderer)
                var cat = PinCategory.Preview;
                var med = MediaType.Video;
                var hr  = _captureGraphBuilder.RenderStream(cat, med, _videoDeviceFilter, _baseGrabFlt, null);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Get the IVideoWindow interface
                _videoWindow = (IVideoWindow)_graphBuilder;

                // Set the video window to be a child of the main window
                hr = _videoWindow.put_Owner(PreviewWindow);

                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Set video window style
                hr = _videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings);

                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Make the video window visible, now that it is properly positioned
                hr = _videoWindow.put_Visible(OABool.True);

                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                _isPreviewRendered = true;
                didSomething       = true;

                var media = new AMMediaType();
                hr = _sampGrabber.GetConnectedMediaType(media);

                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                if (media.formatType != FormatType.VideoInfo || media.formatPtr == IntPtr.Zero)
                {
                    throw new NotSupportedException("Unknown Grabber Media Format");
                }

                _videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader));

                Marshal.FreeCoTaskMem(media.formatPtr); media.formatPtr = IntPtr.Zero;
            }

            if (didSomething)
            {
                _actualGraphState = GraphState.Rendered;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        ///  Create a new filter graph and add filters (devices, compressors, misc),
        ///  but leave the filters unconnected. Call RenderGraph()
        ///  to connect the filters.
        /// </summary>
        void CreateGraph()
        {
            //Skip if already created
            if ((int)_actualGraphState < (int)GraphState.Created)
            {
                // Make a new filter graph
                _graphBuilder = (IGraphBuilder) new FilterGraph();

                // Get the Capture Graph Builder
                _captureGraphBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2();

                // Link the CaptureGraphBuilder to the filter graph
                var hr = _captureGraphBuilder.SetFiltergraph(_graphBuilder);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                var comObj = new SampleGrabber();
                _sampGrabber = (ISampleGrabber)comObj;

                _baseGrabFlt = (IBaseFilter)_sampGrabber;

                var media = new AMMediaType();
                // 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);
                    }

                    media.majorType           = MediaType.Video;
                    media.subType             = MediaSubType.RGB32; //RGB24;
                    media.formatType          = FormatType.VideoInfo;
                    media.temporalCompression = true;               //New

                    hr = _sampGrabber.SetMediaType(media);

                    if (hr < 0)
                    {
                        Marshal.ThrowExceptionForHR(hr);
                    }

                    hr = _graphBuilder.AddFilter(_baseGrabFlt, "Grabber");
                    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
                var cat = PinCategory.Capture;
                var med = MediaType.Interleaved;
                var iid = typeof(IAMStreamConfig).GUID;
                hr = _captureGraphBuilder.FindInterface(cat, med, _videoDeviceFilter, iid, out var o);

                if (hr != 0)
                {
                    // If not found, try looking for a video media type
                    med = MediaType.Video;
                    hr  = _captureGraphBuilder.FindInterface(cat, med, _videoDeviceFilter, iid, out o);

                    if (hr != 0)
                    {
                        // ReSharper disable once RedundantAssignment
                        o = null;
                    }
                }

                //VideoStreamConfig = 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;

                _videoInfoHeader = Marshal.PtrToStructure <VideoInfoHeader>(media.formatPtr);
                Marshal.FreeCoTaskMem(media.formatPtr); media.formatPtr = IntPtr.Zero;

                hr = _sampGrabber.SetBufferSamples(true);

                if (hr == 0)
                {
                    hr = _sampGrabber.SetOneShot(false);
                }

                if (hr == 0)
                {
                    hr = _sampGrabber.SetCallback(null, 0);
                }

                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }
            }

            // Update the state now that we are done
            _actualGraphState = GraphState.Created;
        }