コード例 #1
0
        /// <summary>
        ///  Disconnect and remove all filters except the device
        ///  and compressor filters. This is the opposite of
        ///  renderGraph(). Soem properties such as FrameRate
        ///  can only be set when the device output pins are not
        ///  connected.
        /// </summary>
        protected void DerenderGraph()
        {
            // Stop the graph if it is running (ignore errors)
            MediaControl?.Stop();

            // Free the preview window (ignore errors)
            if (VideoWindow != null)
            {
                VideoWindow.put_Visible(CoreStreaming.DsHlp.OAFALSE);
                VideoWindow.put_Owner(IntPtr.Zero);
                VideoWindow = null;
            }

            // Remove the Resize event handler
            if (PreviewWindow != null)
            {
                PreviewWindow.SizeChanged -= OnPreviewWindowResize;
            }

            if ((int)ActualGraphState >= (int)GraphState.Rendered)
            {
                // Update the state
                ActualGraphState  = GraphState.Created;
                IsPreviewRendered = false;

                // Disconnect all filters downstream of the
                // video and audio devices. If we have a compressor
                // then disconnect it, but don't remove it
                if (VideoDeviceFilter != null)
                {
                    RemoveDownstream(VideoDeviceFilter, VideoCompressor == null);
                }
            }
        }
コード例 #2
0
        /// <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.
            ActualGraphState  = GraphState.Null;
            IsPreviewRendered = false;

            // 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 (VideoCompressorFilter != null)
            {
                GraphBuilder.RemoveFilter(VideoCompressorFilter);
            }
            if (VideoDeviceFilter != null)
            {
                GraphBuilder.RemoveFilter(VideoDeviceFilter);
            }

            // Cleanup
            if (GraphBuilder != null)
            {
                Marshal.ReleaseComObject(GraphBuilder);
            }
            GraphBuilder = null;
            if (CaptureGraphBuilder != null)
            {
                Marshal.ReleaseComObject(CaptureGraphBuilder);
            }
            CaptureGraphBuilder = null;
            if (VideoDeviceFilter != null)
            {
                Marshal.ReleaseComObject(VideoDeviceFilter);
            }
            VideoDeviceFilter = null;
            if (VideoCompressorFilter != null)
            {
                Marshal.ReleaseComObject(VideoCompressorFilter);
            }
            VideoCompressorFilter = null;

            // These are copies of graphBuilder
            MediaControl = null;
            VideoWindow  = null;

            // For unmanaged objects we haven't released explicitly
            GC.Collect();
        }
コード例 #3
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>
        protected void RenderGraph()
        {
            var       didSomething    = false;
            const int WS_CHILD        = 0x40000000;
            const int WS_CLIPCHILDREN = 0x02000000;
            const int WS_CLIPSIBLINGS = 0x04000000;

            // 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 = Uuid.PinCategory.Preview;
                var med = Uuid.MediaType.Video;
                var hr  = CaptureGraphBuilder.RenderStream(ref cat, ref med, VideoDeviceFilter, _baseGrabFlt, null);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Get the IVideoWindow interface
                VideoWindow = (ControlStreaming.IVideoWindow)GraphBuilder;

                // Set the video window to be a child of the main window
                var source = PresentationSource.FromVisual(PreviewWindow) as HwndSource;
                hr = VideoWindow.put_Owner(source.Handle);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Set video window style
                hr = VideoWindow.put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Position video window in client rect of owner window
                PreviewWindow.SizeChanged += OnPreviewWindowResize;
                OnPreviewWindowResize(this, null);

                // Make the video window visible, now that it is properly positioned
                hr = VideoWindow.put_Visible(CoreStreaming.DsHlp.OATRUE);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                IsPreviewRendered = true;
                didSomething      = true;

                var media = new CoreStreaming.AMMediaType();
                hr = SampGrabber.GetConnectedMediaType(media);

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

                _videoInfoHeader = (EditStreaming.VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(EditStreaming.VideoInfoHeader));
                Marshal.FreeCoTaskMem(media.formatPtr); media.formatPtr = IntPtr.Zero;
            }

            if (didSomething)
            {
                ActualGraphState = GraphState.Rendered;
            }
        }
コード例 #4
0
ファイル: CaptureWebcam.cs プロジェクト: dbremner/ScreenToGif
        /// <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.
            ActualGraphState = GraphState.Null;
            IsPreviewRendered = false;

            // 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 (VideoCompressorFilter != null)
                GraphBuilder.RemoveFilter(VideoCompressorFilter);
            if (VideoDeviceFilter != null)
                GraphBuilder.RemoveFilter(VideoDeviceFilter);

            // Cleanup
            if (GraphBuilder != null)
                Marshal.ReleaseComObject(GraphBuilder); GraphBuilder = null;
            if (CaptureGraphBuilder != null)
                Marshal.ReleaseComObject(CaptureGraphBuilder); CaptureGraphBuilder = null;
            if (VideoDeviceFilter != null)
                Marshal.ReleaseComObject(VideoDeviceFilter); VideoDeviceFilter = null;
            if (VideoCompressorFilter != null)
                Marshal.ReleaseComObject(VideoCompressorFilter); VideoCompressorFilter = null;

            // These are copies of graphBuilder
            MediaControl = null;
            VideoWindow = null;

            // For unmanaged objects we haven't released explicitly
            GC.Collect();
        }
コード例 #5
0
ファイル: CaptureWebcam.cs プロジェクト: dbremner/ScreenToGif
        /// <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>
        protected void RenderGraph()
        {
            Guid cat;
            Guid med;
            int hr;
            bool didSomething = false;
            const int WS_CHILD = 0x40000000;
            const int WS_CLIPCHILDREN = 0x02000000;
            const int WS_CLIPSIBLINGS = 0x04000000;

            // Stop the graph
            if (MediaControl != null)
                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)
                cat = Uuid.PinCategory.Preview;
                med = Uuid.MediaType.Video;
                hr = CaptureGraphBuilder.RenderStream(ref cat, ref med, VideoDeviceFilter, _baseGrabFlt, null);
                if (hr < 0) Marshal.ThrowExceptionForHR(hr);

                // Get the IVideoWindow interface
                VideoWindow = (ControlStreaming.IVideoWindow)GraphBuilder;

                // Set the video window to be a child of the main window
                var source = PresentationSource.FromVisual(PreviewWindow) as HwndSource;
                hr = VideoWindow.put_Owner(source.Handle);
                if (hr < 0) Marshal.ThrowExceptionForHR(hr);

                // Set video window style
                hr = VideoWindow.put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
                if (hr < 0) Marshal.ThrowExceptionForHR(hr);

                // Position video window in client rect of owner window
                PreviewWindow.SizeChanged += OnPreviewWindowResize;
                OnPreviewWindowResize(this, null);

                // Make the video window visible, now that it is properly positioned
                hr = VideoWindow.put_Visible(CoreStreaming.DsHlp.OATRUE);
                if (hr < 0) Marshal.ThrowExceptionForHR(hr);

                IsPreviewRendered = true;
                didSomething = true;

                var media = new CoreStreaming.AMMediaType();
                hr = SampGrabber.GetConnectedMediaType(media);

                if (hr < 0)
                    Marshal.ThrowExceptionForHR(hr);
                if ((media.formatType != Uuid.FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero))
                    throw new NotSupportedException("Unknown Grabber Media Format");

                _videoInfoHeader = (EditStreaming.VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(EditStreaming.VideoInfoHeader));
                Marshal.FreeCoTaskMem(media.formatPtr); media.formatPtr = IntPtr.Zero;
            }

            if (didSomething)
                ActualGraphState = GraphState.Rendered;
        }
コード例 #6
0
ファイル: CaptureWebcam.cs プロジェクト: dbremner/ScreenToGif
        /// <summary>
        ///  Disconnect and remove all filters except the device
        ///  and compressor filters. This is the opposite of
        ///  renderGraph(). Soem properties such as FrameRate
        ///  can only be set when the device output pins are not
        ///  connected. 
        /// </summary>
        protected void DerenderGraph()
        {
            // Stop the graph if it is running (ignore errors)
            if (MediaControl != null)
                MediaControl.Stop();

            // Free the preview window (ignore errors)
            if (VideoWindow != null)
            {
                VideoWindow.put_Visible(CoreStreaming.DsHlp.OAFALSE);
                VideoWindow.put_Owner(IntPtr.Zero);
                VideoWindow = null;
            }

            // Remove the Resize event handler
            if (PreviewWindow != null)
                PreviewWindow.SizeChanged -= new SizeChangedEventHandler(OnPreviewWindowResize);

            if ((int)ActualGraphState >= (int)GraphState.Rendered)
            {
                // Update the state
                ActualGraphState = GraphState.Created;
                IsPreviewRendered = false;

                // Disconnect all filters downstream of the 
                // video and audio devices. If we have a compressor
                // then disconnect it, but don't remove it
                if (VideoDeviceFilter != null)
                    RemoveDownstream(VideoDeviceFilter, (VideoCompressor == null));
            }
        }