Beispiel #1
0
        /// <summary>
        /// Called from RenderWindow to add the renderer to the graph, create a sample grabber, add it
        /// to the graph and connect it all up
        /// </summary>
        /// <param name="icgb">ICaptureGraphBuilder2 to use</param>
        /// <param name="pCallback">ICaptureGraphBuilder2 to use</param>
        /// <param name="sType">String to use in creating filter graph object descriptions</param>
        /// <param name="pPin">Pin to connect from</param>
        /// <param name="ibfRenderer">Renderer to add</param>
        protected void RenderWindowHelper(ICaptureGraphBuilder2 icgb, CallbackHandler pCallback, string sType, IPin pPin,
                                          IBaseFilter ibfRenderer)
        {
            int hr;

            // Add the renderer to the graph
            hr = _graph.AddFilter(ibfRenderer, sType + " Renderer");
            _dc.Add(ibfRenderer);
            DESError.ThrowExceptionForHR(hr);

            // Do everything else
            RenderHelper(icgb, pCallback, sType, pPin, null, ibfRenderer);
        }
Beispiel #2
0
        /// <summary>
        /// Common routine used by RenderTo*
        /// </summary>
        /// <param name="icgb">ICaptureGraphBuilder2 to use</param>
        /// <param name="pCallback">Callback to use (or null)</param>
        /// <param name="sType">string to use in creating filter graph object descriptions</param>
        /// <param name="pPin">Pin to connect from</param>
        /// <param name="ibfCompressor">Compressor to use, or null for none</param>
        /// <param name="pOutput">Endpoint (renderer or file writer) to connect to</param>
        protected void RenderHelper(ICaptureGraphBuilder2 icgb, CallbackHandler pCallback, string sType, IPin pPin,
                                    IBaseFilter ibfCompressor, IBaseFilter pOutput)
        {
            int         hr;
            IBaseFilter ibfSampleGrabber = null;

            try
            {
                // If no callback was provided, don't create a samplegrabber
                if (pCallback != null)
                {
                    ISampleGrabber isg = (ISampleGrabber) new SampleGrabber();
                    ibfSampleGrabber = (IBaseFilter)isg;
                    _dc.Add(ibfSampleGrabber);

                    hr = isg.SetCallback(pCallback, 1);
                    DESError.ThrowExceptionForHR(hr);

                    hr = _graph.AddFilter(ibfSampleGrabber, sType + " sample grabber");
                    DESError.ThrowExceptionForHR(hr);
                }

                // If a compressor was provided, add it to the graph and connect it up
                if (ibfCompressor != null)
                {
                    // Connect the pin.
                    hr = _graph.AddFilter(ibfCompressor, sType + " Compressor");
                    DESError.ThrowExceptionForHR(hr);

                    FilterGraphTools.ConnectFilters(_graph, pPin, ibfSampleGrabber, true);

                    FilterGraphTools.ConnectFilters(_graph, ibfSampleGrabber, ibfCompressor, true);

                    FilterGraphTools.ConnectFilters(_graph, ibfCompressor, pOutput, true);
                }
                else
                {
                    // Just connect the SampleGrabber (if any)
                    hr = icgb.RenderStream(null, null, pPin, ibfSampleGrabber, pOutput);
                    DESError.ThrowExceptionForHR(hr);
                }
            }
            finally
            {
                if (ibfSampleGrabber != null)
                {
                    Marshal.ReleaseComObject(ibfSampleGrabber);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Configure the graph to output the results to a video window.
        /// </summary>
        /// <remarks>
        /// The callback routines are invoked once for each sample.  This allows for additional processing to
        /// be performed on the video or audio buffers.
        /// </remarks>
        /// <param name="windowHandle">Window handle to render to, or IntPtr.Zero to render to its own window</param>
        /// <param name="videoParticipants">Callback routine to be called for each video frame or null for no callback</param>
        /// <param name="audioParticipants">Callback routine to be called for each audio frame or null for no callback</param>
        private void RenderToWindow(IntPtr windowHandle, ICallbackParticipant[] videoParticipants,
                                    ICallbackParticipant[] audioParticipants)
        {
            int hr;
            IPin pin;
            IVideoWindow videoWindow;
            IAMTimelineObj group;
            IAMTimeline desTimeline = Timeline.DesTimeline;

            // Contains useful routines for creating the graph
            var graphBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2();

            try
            {
                hr = graphBuilder.SetFiltergraph(Graph);
                DESError.ThrowExceptionForHR(hr);

                int NumGroups;
                hr = desTimeline.GetGroupCount(out NumGroups);
                DESError.ThrowExceptionForHR(hr);

                // Walk the groups.  For DESCombine, there is one group that
                // contains all the video, and a second group for the audio.
                for (int i = 0; i < NumGroups; i++)
                {
                    hr = desTimeline.GetGroup(out group, i);
                    DESError.ThrowExceptionForHR(hr);

                    try
                    {
                        // Inform the graph we will be previewing (rather than writing to disk)
                        var pTLGroup = (IAMTimelineGroup) group;
                        hr = pTLGroup.SetPreviewMode(true);
                        DESError.ThrowExceptionForHR(hr);
                    }
                    finally
                    {
                        // Release the group
                        Marshal.ReleaseComObject(group);
                    }

                    // Get the IPin for the current group
                    hr = RenderEngine.GetGroupOutputPin(i, out pin);
                    DESError.ThrowExceptionForHR(hr);

                    try
                    {
                        // If this is the video pin
                        if (FilterGraphTools.IsVideo(pin))
                        {
                            // Get a video renderer
                            var ibfVideoRenderer = (IBaseFilter) new VideoRenderer();

                            try
                            {
                                // Create a sample grabber, add it to the graph and connect it all up
                                var mcb =
                                    new CallbackHandler(videoParticipants);
                                RenderWindowHelper(graphBuilder, mcb, "Video", pin, ibfVideoRenderer);
                            }
                            finally
                            {
                                Marshal.ReleaseComObject(ibfVideoRenderer);
                            }
                        }
                        else
                        {
                            // Get an audio renderer
                            var ibfAudioRenderer = (IBaseFilter) new AudioRender();

                            try
                            {
                                // Create a sample grabber, add it to the graph and connect it all up
                                var mcb =
                                    new CallbackHandler(audioParticipants);
                                RenderWindowHelper(graphBuilder, mcb, "Audio", pin, ibfAudioRenderer);
                            }
                            finally
                            {
                                Marshal.ReleaseComObject(ibfAudioRenderer);
                            }
                        }
                    }
                    finally
                    {
                        Marshal.ReleaseComObject(pin);
                    }
                }

                // Configure the video window
                videoWindow = (IVideoWindow) Graph;

                // If a window handle was supplied, use it
                if (windowHandle != IntPtr.Zero)
                {
                    hr = videoWindow.put_Owner(windowHandle);
                    DESError.ThrowExceptionForHR(hr);
                }
                else
                {
                    // Use our own window

                    hr = videoWindow.put_Caption(Resources.DefaultVideoRenderingWindowCaption);
                    DESError.ThrowExceptionForHR(hr);

                    // since no user interaction is allowed, remove
                    // system menu and maximize/minimize buttons
                    WindowStyle lStyle = 0;
                    hr = videoWindow.get_WindowStyle(out lStyle);
                    DESError.ThrowExceptionForHR(hr);

                    lStyle &= ~(WindowStyle.MinimizeBox | WindowStyle.MaximizeBox | WindowStyle.SysMenu);
                    hr = videoWindow.put_WindowStyle(lStyle);
                    DESError.ThrowExceptionForHR(hr);
                }
            }
            finally
            {
                Marshal.ReleaseComObject(graphBuilder);
            }
        }
Beispiel #4
0
        protected void RenderGroups(ICaptureGraphBuilder2 graphBuilder, IBaseFilter audioCompressor,
                                    IBaseFilter videoCompressor,
                                    IBaseFilter audioDestination, IBaseFilter videoDestination,
                                    ICallbackParticipant[] audioParticipants,
                                    ICallbackParticipant[] videoParticipants)
        {
            int hr = 0;

            if (audioCompressor != null) _cleanup.Add(audioCompressor);
            if (videoCompressor != null) _cleanup.Add(videoCompressor);
            if (audioDestination != null) _cleanup.Add(audioDestination);
            if ((videoDestination != null) && (audioDestination != videoDestination)) _cleanup.Add(videoDestination);

            IAMTimeline desTimeline = _timeline.DesTimeline;

            int groupCount;
            hr = desTimeline.GetGroupCount(out groupCount);
            DESError.ThrowExceptionForHR(hr);

            // Walk the groups.  For this class, there is one group that
            // contains all the video, and a second group for the audio.
            for (int i = (groupCount - 1); i >= 0; i--)
            {
                IAMTimelineObj group;

                hr = desTimeline.GetGroup(out group, i);
                DESError.ThrowExceptionForHR(hr);

                try
                {
                    // Inform the graph we will be writing to disk (rather than previewing)
                    var timelineGroup = (IAMTimelineGroup) group;
                    hr = timelineGroup.SetPreviewMode(false);
                    DESError.ThrowExceptionForHR(hr);
                }
                finally
                {
                    Marshal.ReleaseComObject(group);
                }

                IPin pPin;

                // Get the IPin for the current group
                hr = _renderEngine.GetGroupOutputPin(i, out pPin);
                _cleanup.Add(pPin);
                DESError.ThrowExceptionForHR(hr);

                try
                {
                    if (FilterGraphTools.IsVideo(pPin))
                    {
                        // Create a sample grabber, add it to the graph and connect it all up
                        var mcb =
                            new CallbackHandler(videoParticipants);
                        RenderHelper(graphBuilder, mcb, "Video", pPin, videoCompressor, videoDestination);
                    }
                    else
                    {
                        // Create a sample grabber, add it to the graph and connect it all up
                        var mcb =
                            new CallbackHandler(audioParticipants);
                        RenderHelper(graphBuilder, mcb, "Audio", pPin, audioCompressor, audioDestination);
                    }
                }
                finally
                {
                    Marshal.ReleaseComObject(pPin);
                }
            }
        }
Beispiel #5
0
        protected void RenderGroups(ICaptureGraphBuilder2 graphBuilder, IBaseFilter audioCompressor,
                                    IBaseFilter videoCompressor,
                                    IBaseFilter audioDestination, IBaseFilter videoDestination,
                                    ICallbackParticipant[] audioParticipants,
                                    ICallbackParticipant[] videoParticipants)
        {
            int hr = 0;

            if (audioCompressor != null)
            {
                _cleanup.Add(audioCompressor);
            }
            if (videoCompressor != null)
            {
                _cleanup.Add(videoCompressor);
            }
            if (audioDestination != null)
            {
                _cleanup.Add(audioDestination);
            }
            if ((videoDestination != null) && (audioDestination != videoDestination))
            {
                _cleanup.Add(videoDestination);
            }

            IAMTimeline desTimeline = _timeline.DesTimeline;

            int groupCount;

            hr = desTimeline.GetGroupCount(out groupCount);
            DESError.ThrowExceptionForHR(hr);

            // Walk the groups.  For this class, there is one group that
            // contains all the video, and a second group for the audio.
            for (int i = (groupCount - 1); i >= 0; i--)
            {
                IAMTimelineObj group;

                hr = desTimeline.GetGroup(out group, i);
                DESError.ThrowExceptionForHR(hr);

                try
                {
                    // Inform the graph we will be writing to disk (rather than previewing)
                    var timelineGroup = (IAMTimelineGroup)group;
                    hr = timelineGroup.SetPreviewMode(false);
                    DESError.ThrowExceptionForHR(hr);
                }
                finally
                {
                    Marshal.ReleaseComObject(group);
                }

                IPin pPin;

                // Get the IPin for the current group
                hr = _renderEngine.GetGroupOutputPin(i, out pPin);
                _cleanup.Add(pPin);
                DESError.ThrowExceptionForHR(hr);

                try
                {
                    if (FilterGraphTools.IsVideo(pPin))
                    {
                        // Create a sample grabber, add it to the graph and connect it all up
                        var mcb =
                            new CallbackHandler(videoParticipants);
                        RenderHelper(graphBuilder, mcb, "Video", pPin, videoCompressor, videoDestination);
                    }
                    else
                    {
                        // Create a sample grabber, add it to the graph and connect it all up
                        var mcb =
                            new CallbackHandler(audioParticipants);
                        RenderHelper(graphBuilder, mcb, "Audio", pPin, audioCompressor, audioDestination);
                    }
                }
                finally
                {
                    Marshal.ReleaseComObject(pPin);
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Configure the graph to output the results to a video window.
        /// </summary>
        /// <remarks>
        /// The callback routines are invoked once for each sample.  This allows for additional processing to
        /// be performed on the video or audio buffers.
        /// </remarks>
        /// <param name="hWnd">Window handle to render to, or IntPtr.Zero to render to its own window</param>
        /// <param name="pVideoCallback">Callback routine to be called for each video frame or null for no callback</param>
        /// <param name="pAudioCallback">Callback routine to be called for each audio frame or null for no callback</param>
        private void RenderToWindow(IntPtr hWnd, IDESCombineCB pVideoCallback, IDESCombineCB pAudioCallback)
        {
            int            hr;
            IPin           pPin;
            IVideoWindow   pVidWindow;
            IAMTimelineObj pGroup;
            IAMTimeline    desTimeline = _timeline.DesTimeline;

            // Contains useful routines for creating the graph
            ICaptureGraphBuilder2 icgb = (ICaptureGraphBuilder2) new CaptureGraphBuilder2();

            try
            {
                hr = icgb.SetFiltergraph(_graph);
                DESError.ThrowExceptionForHR(hr);

                int NumGroups;
                hr = desTimeline.GetGroupCount(out NumGroups);
                DESError.ThrowExceptionForHR(hr);

                // Walk the groups.  For DESCombine, there is one group that
                // contains all the video, and a second group for the audio.
                for (int i = 0; i < NumGroups; i++)
                {
                    hr = desTimeline.GetGroup(out pGroup, i);
                    DESError.ThrowExceptionForHR(hr);

                    try
                    {
                        // Inform the graph we will be previewing (rather than writing to disk)
                        IAMTimelineGroup pTLGroup = (IAMTimelineGroup)pGroup;
                        hr = pTLGroup.SetPreviewMode(true);
                        DESError.ThrowExceptionForHR(hr);
                    }
                    finally
                    {
                        // Release the group
                        Marshal.ReleaseComObject(pGroup);
                    }

                    // Get the IPin for the current group
                    hr = _renderEngine.GetGroupOutputPin(i, out pPin);
                    DESError.ThrowExceptionForHR(hr);

                    try
                    {
                        // If this is the video pin
                        if (PinUtils.IsVideo(pPin))
                        {
                            // Get a video renderer
                            IBaseFilter ibfVideoRenderer = (IBaseFilter) new VideoRenderer();

                            try
                            {
                                // Create a sample grabber, add it to the graph and connect it all up
                                CallbackHandler mcb =
                                    new CallbackHandler(_firstVideoGroup, pVideoCallback, (IMediaEventSink)_graph,
                                                        EC_VideoFileComplete);
                                RenderWindowHelper(icgb, mcb, "Video", pPin, ibfVideoRenderer);
                            }
                            finally
                            {
                                Marshal.ReleaseComObject(ibfVideoRenderer);
                            }
                        }
                        else
                        {
                            // Get an audio renderer
                            IBaseFilter ibfAudioRenderer = (IBaseFilter) new AudioRender();

                            try
                            {
                                // Create a sample grabber, add it to the graph and connect it all up
                                CallbackHandler mcb =
                                    new CallbackHandler(_firstAudioGroup, pAudioCallback, (IMediaEventSink)_graph,
                                                        EC_AudioFileComplete);
                                RenderWindowHelper(icgb, mcb, "Audio", pPin, ibfAudioRenderer);
                            }
                            finally
                            {
                                Marshal.ReleaseComObject(ibfAudioRenderer);
                            }
                        }
                    }
                    finally
                    {
                        Marshal.ReleaseComObject(pPin);
                    }
                }

                // Configure the video window
                pVidWindow = (IVideoWindow)_graph;

                // If a window handle was supplied, use it
                if (hWnd != IntPtr.Zero)
                {
                    hr = pVidWindow.put_Owner(hWnd);
                    DESError.ThrowExceptionForHR(hr);
                }
                else
                {
                    // Use our own window

                    hr = pVidWindow.put_Caption("Video Rendering Window");
                    DESError.ThrowExceptionForHR(hr);

                    // since no user interaction is allowed, remove
                    // system menu and maximize/minimize buttons
                    WindowStyle lStyle = 0;
                    hr = pVidWindow.get_WindowStyle(out lStyle);
                    DESError.ThrowExceptionForHR(hr);

                    lStyle &= ~(WindowStyle.MinimizeBox | WindowStyle.MaximizeBox | WindowStyle.SysMenu);
                    hr      = pVidWindow.put_WindowStyle(lStyle);
                    DESError.ThrowExceptionForHR(hr);
                }
            }
            finally
            {
                Marshal.ReleaseComObject(icgb);
            }
        }
Beispiel #7
0
        protected void RenderGroups(ICaptureGraphBuilder2 icgb, IBaseFilter audioCompressor, IBaseFilter videoCompressor,
                                    IBaseFilter audioDest, IBaseFilter videoDest, IDESCombineCB pAudioCallback,
                                    IDESCombineCB pVideoCallback)
        {
            int hr = 0;

            if (audioCompressor != null)
            {
                _dc.Add(audioCompressor);
            }
            if (videoCompressor != null)
            {
                _dc.Add(videoCompressor);
            }
            if (audioDest != null)
            {
                _dc.Add(audioDest);
            }
            if ((videoDest != null) && (audioDest != videoDest))
            {
                _dc.Add(videoDest);
            }

            IAMTimeline desTimeline = _timeline.DesTimeline;

            int NumGroups;

            hr = desTimeline.GetGroupCount(out NumGroups);
            DESError.ThrowExceptionForHR(hr);

            // Walk the groups.  For this class, there is one group that
            // contains all the video, and a second group for the audio.
            for (int i = (NumGroups - 1); i >= 0; i--)
            {
                IAMTimelineObj pGroup;

                hr = desTimeline.GetGroup(out pGroup, i);
                DESError.ThrowExceptionForHR(hr);

                try
                {
                    // Inform the graph we will be writing to disk (rather than previewing)
                    IAMTimelineGroup pTLGroup = (IAMTimelineGroup)pGroup;
                    hr = pTLGroup.SetPreviewMode(false);
                    DESError.ThrowExceptionForHR(hr);
                }
                finally
                {
                    Marshal.ReleaseComObject(pGroup);
                }

                IPin pPin;

                // Get the IPin for the current group
                hr = _renderEngine.GetGroupOutputPin(i, out pPin);
                _dc.Add(pPin);
                DESError.ThrowExceptionForHR(hr);

                try
                {
                    if (PinUtils.IsVideo(pPin))
                    {
                        // Create a sample grabber, add it to the graph and connect it all up
                        CallbackHandler mcb =
                            new CallbackHandler(_firstVideoGroup, pVideoCallback, (IMediaEventSink)_graph,
                                                EC_VideoFileComplete);
                        RenderHelper(icgb, mcb, "Video", pPin, videoCompressor, videoDest);
                    }
                    else
                    {
                        // Create a sample grabber, add it to the graph and connect it all up
                        CallbackHandler mcb =
                            new CallbackHandler(_firstAudioGroup, pAudioCallback, (IMediaEventSink)_graph,
                                                EC_AudioFileComplete);
                        RenderHelper(icgb, mcb, "Audio", pPin, audioCompressor, audioDest);
                    }
                }
                finally
                {
                    Marshal.ReleaseComObject(pPin);
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Configure the graph to output the results to a video window.
        /// </summary>
        /// <remarks>
        /// The callback routines are invoked once for each sample.  This allows for additional processing to
        /// be performed on the video or audio buffers.
        /// </remarks>
        /// <param name="windowHandle">Window handle to render to, or IntPtr.Zero to render to its own window</param>
        /// <param name="videoParticipants">Callback routine to be called for each video frame or null for no callback</param>
        /// <param name="audioParticipants">Callback routine to be called for each audio frame or null for no callback</param>
        private void RenderToWindow(IntPtr windowHandle, ICallbackParticipant[] videoParticipants,
                                    ICallbackParticipant[] audioParticipants)
        {
            int            hr;
            IPin           pin;
            IVideoWindow   videoWindow;
            IAMTimelineObj group;
            IAMTimeline    desTimeline = Timeline.DesTimeline;

            // Contains useful routines for creating the graph
            var graphBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2();

            try
            {
                hr = graphBuilder.SetFiltergraph(Graph);
                DESError.ThrowExceptionForHR(hr);

                int NumGroups;
                hr = desTimeline.GetGroupCount(out NumGroups);
                DESError.ThrowExceptionForHR(hr);

                // Walk the groups.  For DESCombine, there is one group that
                // contains all the video, and a second group for the audio.
                for (int i = 0; i < NumGroups; i++)
                {
                    hr = desTimeline.GetGroup(out group, i);
                    DESError.ThrowExceptionForHR(hr);

                    try
                    {
                        // Inform the graph we will be previewing (rather than writing to disk)
                        var pTLGroup = (IAMTimelineGroup)group;
                        hr = pTLGroup.SetPreviewMode(true);
                        DESError.ThrowExceptionForHR(hr);
                    }
                    finally
                    {
                        // Release the group
                        Marshal.ReleaseComObject(group);
                    }

                    // Get the IPin for the current group
                    hr = RenderEngine.GetGroupOutputPin(i, out pin);
                    DESError.ThrowExceptionForHR(hr);

                    try
                    {
                        // If this is the video pin
                        if (FilterGraphTools.IsVideo(pin))
                        {
                            // Get a video renderer
                            var ibfVideoRenderer = (IBaseFilter) new VideoRenderer();

                            try
                            {
                                // Create a sample grabber, add it to the graph and connect it all up
                                var mcb =
                                    new CallbackHandler(videoParticipants);
                                RenderWindowHelper(graphBuilder, mcb, "Video", pin, ibfVideoRenderer);
                            }
                            finally
                            {
                                Marshal.ReleaseComObject(ibfVideoRenderer);
                            }
                        }
                        else
                        {
                            // Get an audio renderer
                            var ibfAudioRenderer = (IBaseFilter) new AudioRender();

                            try
                            {
                                // Create a sample grabber, add it to the graph and connect it all up
                                var mcb =
                                    new CallbackHandler(audioParticipants);
                                RenderWindowHelper(graphBuilder, mcb, "Audio", pin, ibfAudioRenderer);
                            }
                            finally
                            {
                                Marshal.ReleaseComObject(ibfAudioRenderer);
                            }
                        }
                    }
                    finally
                    {
                        Marshal.ReleaseComObject(pin);
                    }
                }

                // Configure the video window
                videoWindow = (IVideoWindow)Graph;

                // If a window handle was supplied, use it
                if (windowHandle != IntPtr.Zero)
                {
                    hr = videoWindow.put_Owner(windowHandle);
                    DESError.ThrowExceptionForHR(hr);
                }
                else
                {
                    // Use our own window

                    hr = videoWindow.put_Caption(Resources.DefaultVideoRenderingWindowCaption);
                    DESError.ThrowExceptionForHR(hr);

                    // since no user interaction is allowed, remove
                    // system menu and maximize/minimize buttons
                    WindowStyle lStyle = 0;
                    hr = videoWindow.get_WindowStyle(out lStyle);
                    DESError.ThrowExceptionForHR(hr);

                    lStyle &= ~(WindowStyle.MinimizeBox | WindowStyle.MaximizeBox | WindowStyle.SysMenu);
                    hr      = videoWindow.put_WindowStyle(lStyle);
                    DESError.ThrowExceptionForHR(hr);
                }
            }
            finally
            {
                Marshal.ReleaseComObject(graphBuilder);
            }
        }