Dispose() public method

Dispose the object.
public Dispose ( ) : void
return void
コード例 #1
0
        private void WorkerThread( bool runGraph )
        {
            ReasonToFinishPlaying reasonToStop = ReasonToFinishPlaying.StoppedByUser;
            bool isSapshotSupported = false;

            // grabber
            Grabber videoGrabber = new Grabber( this, false );
            Grabber snapshotGrabber = new Grabber( this, true );

            // objects
            object captureGraphObject = null;
            object graphObject = null;
            object videoGrabberObject = null;
            object snapshotGrabberObject = null;
            object crossbarObject = null;

            // interfaces
            ICaptureGraphBuilder2 captureGraph = null;
            IFilterGraph2   graph = null;
            IBaseFilter     sourceBase = null;
            IBaseFilter     videoGrabberBase = null;
            IBaseFilter     snapshotGrabberBase = null;
            ISampleGrabber  videoSampleGrabber = null;
            ISampleGrabber  snapshotSampleGrabber = null;
            IMediaControl   mediaControl = null;
            IAMVideoControl videoControl = null;
            IMediaEventEx   mediaEvent = null;
            IPin            pinStillImage = null;
            IAMCrossbar     crossbar = null;

            try
            {
                // get type of capture graph builder
                Type type = Type.GetTypeFromCLSID( Clsid.CaptureGraphBuilder2 );
                if ( type == null )
                    throw new ApplicationException( "Failed creating capture graph builder" );

                // create capture graph builder
                captureGraphObject = Activator.CreateInstance( type );
                captureGraph = (ICaptureGraphBuilder2) captureGraphObject;

                // get type of filter graph
                type = Type.GetTypeFromCLSID( Clsid.FilterGraph );
                if ( type == null )
                    throw new ApplicationException( "Failed creating filter graph" );

                // create filter graph
                graphObject = Activator.CreateInstance( type );
                graph = (IFilterGraph2) graphObject;

                // set filter graph to the capture graph builder
                captureGraph.SetFiltergraph( (IGraphBuilder) graph );

                // create source device's object
                sourceObject = FilterInfo.CreateFilter( deviceMoniker );
                if ( sourceObject == null )
                    throw new ApplicationException( "Failed creating device object for moniker" );

                // get base filter interface of source device
                sourceBase = (IBaseFilter) sourceObject;

                // get video control interface of the device
                try
                {
                    videoControl = (IAMVideoControl) sourceObject;
                }
                catch
                {
                    // some camera drivers may not support IAMVideoControl interface
                }

                // get type of sample grabber
                type = Type.GetTypeFromCLSID( Clsid.SampleGrabber );
                if ( type == null )
                    throw new ApplicationException( "Failed creating sample grabber" );

                // create sample grabber used for video capture
                videoGrabberObject = Activator.CreateInstance( type );
                videoSampleGrabber = (ISampleGrabber) videoGrabberObject;
                videoGrabberBase = (IBaseFilter) videoGrabberObject;
                // create sample grabber used for snapshot capture
                snapshotGrabberObject = Activator.CreateInstance( type );
                snapshotSampleGrabber = (ISampleGrabber) snapshotGrabberObject;
                snapshotGrabberBase = (IBaseFilter) snapshotGrabberObject;

                // add source and grabber filters to graph
                graph.AddFilter( sourceBase, "source" );
                graph.AddFilter( videoGrabberBase, "grabber_video" );
                graph.AddFilter( snapshotGrabberBase, "grabber_snapshot" );

                // set media type
                AMMediaType mediaType = new AMMediaType( );
                mediaType.MajorType = MediaType.Video;
                mediaType.SubType   = MediaSubType.RGB24;

                videoSampleGrabber.SetMediaType( mediaType );
                snapshotSampleGrabber.SetMediaType( mediaType );

                // get crossbar object to to allows configuring pins of capture card
                captureGraph.FindInterface( FindDirection.UpstreamOnly, Guid.Empty, sourceBase, typeof( IAMCrossbar ).GUID, out crossbarObject );
                if ( crossbarObject != null )
                {
                    crossbar = (IAMCrossbar) crossbarObject;
                }
                isCrossbarAvailable = ( crossbar != null );
                crossbarVideoInputs = ColletCrossbarVideoInputs( crossbar );

                if ( videoControl != null )
                {
                    // find Still Image output pin of the vedio device
                    captureGraph.FindPin( sourceObject, PinDirection.Output,
                        PinCategory.StillImage, MediaType.Video, false, 0, out pinStillImage );
                    // check if it support trigger mode
                    if ( pinStillImage != null )
                    {
                        VideoControlFlags caps;
                        videoControl.GetCaps( pinStillImage, out caps );
                        isSapshotSupported = ( ( caps & VideoControlFlags.ExternalTriggerEnable ) != 0 );
                    }
                }

                // configure video sample grabber
                videoSampleGrabber.SetBufferSamples( false );
                videoSampleGrabber.SetOneShot( false );
                videoSampleGrabber.SetCallback( videoGrabber, 1 );

                // configure snapshot sample grabber
                snapshotSampleGrabber.SetBufferSamples( true );
                snapshotSampleGrabber.SetOneShot( false );
                snapshotSampleGrabber.SetCallback( snapshotGrabber, 1 );

                // configure pins
                GetPinCapabilitiesAndConfigureSizeAndRate( captureGraph, sourceBase,
                    PinCategory.Capture, desiredFrameSize, desiredFrameRate, ref videoCapabilities );
                if ( isSapshotSupported )
                {
                    GetPinCapabilitiesAndConfigureSizeAndRate( captureGraph, sourceBase,
                        PinCategory.StillImage, desiredSnapshotSize, 0, ref snapshotCapabilities );
                }
                else
                {
                    snapshotCapabilities = new VideoCapabilities[0];
                }

                // put video/snapshot capabilities into cache
                lock ( cacheVideoCapabilities )
                {
                    if ( ( videoCapabilities != null ) && ( !cacheVideoCapabilities.ContainsKey( deviceMoniker ) ) )
                    {
                        cacheVideoCapabilities.Add( deviceMoniker, videoCapabilities );
                    }
                }
                lock ( cacheSnapshotCapabilities )
                {
                    if ( ( snapshotCapabilities != null ) && ( !cacheSnapshotCapabilities.ContainsKey( deviceMoniker ) ) )
                    {
                        cacheSnapshotCapabilities.Add( deviceMoniker, snapshotCapabilities );
                    }
                }

                if ( runGraph )
                {
                    // render capture pin
                    captureGraph.RenderStream( PinCategory.Capture, MediaType.Video, sourceBase, null, videoGrabberBase );

                    if ( videoSampleGrabber.GetConnectedMediaType( mediaType ) == 0 )
                    {
                        VideoInfoHeader vih = (VideoInfoHeader) Marshal.PtrToStructure( mediaType.FormatPtr, typeof( VideoInfoHeader ) );

                        videoGrabber.Width = vih.BmiHeader.Width;
                        videoGrabber.Height = vih.BmiHeader.Height;
                        
                        mediaType.Dispose( );
                    }

                    if ( ( isSapshotSupported ) && ( provideSnapshots ) )
                    {
                        // render snapshot pin
                        captureGraph.RenderStream( PinCategory.StillImage, MediaType.Video, sourceBase, null, snapshotGrabberBase );

                        if ( snapshotSampleGrabber.GetConnectedMediaType( mediaType ) == 0 )
                        {
                            VideoInfoHeader vih = (VideoInfoHeader) Marshal.PtrToStructure( mediaType.FormatPtr, typeof( VideoInfoHeader ) );

                            snapshotGrabber.Width  = vih.BmiHeader.Width;
                            snapshotGrabber.Height = vih.BmiHeader.Height;

                            mediaType.Dispose( );
                        }
                    }

                    // get media control
                    mediaControl = (IMediaControl) graphObject;

                    // get media events' interface
                    mediaEvent = (IMediaEventEx) graphObject;
                    IntPtr p1, p2;
                    DsEvCode code;

                    // run
                    mediaControl.Run( );

                    if ( ( isSapshotSupported ) && ( provideSnapshots ) )
                    {
                        startTime = DateTime.Now;
                        videoControl.SetMode( pinStillImage, VideoControlFlags.ExternalTriggerEnable );
                    }

                    do
                    {
                        if ( mediaEvent != null )
                        {
                            if ( mediaEvent.GetEvent( out code, out p1, out p2, 0 ) >= 0 )
                            {
                                mediaEvent.FreeEventParams( code, p1, p2 );

                                if ( code == DsEvCode.DeviceLost )
                                {
                                    reasonToStop = ReasonToFinishPlaying.DeviceLost;
                                    break;
                                }
                            }
                        }

                        if ( needToSetVideoInput )
                        {
                            needToSetVideoInput = false;
                            // set/check current input type of a video card (frame grabber)
                            if ( isCrossbarAvailable.Value )
                            {
                                SetCurrentCrossbarInput( crossbar, crossbarVideoInput );
                                crossbarVideoInput = GetCurrentCrossbarInput( crossbar );
                            }
                        }

                        if ( needToSimulateTrigger )
                        {
                            needToSimulateTrigger = false;

                            if ( ( isSapshotSupported ) && ( provideSnapshots ) )
                            {
                                videoControl.SetMode( pinStillImage, VideoControlFlags.Trigger );
                            }
                        }

                        if ( needToDisplayPropertyPage )
                        {
                            needToDisplayPropertyPage = false;
                            DisplayPropertyPage( parentWindowForPropertyPage, sourceObject );

                            if ( crossbar != null )
                            {
                                crossbarVideoInput = GetCurrentCrossbarInput( crossbar );
                            }
                        }

                        if ( needToDisplayCrossBarPropertyPage )
                        {
                            needToDisplayCrossBarPropertyPage = false;

                            if ( crossbar != null )
                            {
                                DisplayPropertyPage( parentWindowForPropertyPage, crossbar );
                                crossbarVideoInput = GetCurrentCrossbarInput( crossbar );
                            }
                        }
                    }
                    while ( !stopEvent.WaitOne( 100, false ) );

                    mediaControl.Stop( );
                }
            }
            catch ( Exception exception )
            {
                // provide information to clients
                if ( VideoSourceError != null )
                {
                    VideoSourceError( this, new VideoSourceErrorEventArgs( exception.Message ) );
                }
            }
            finally
            {
                // release all objects
                captureGraph    = null;
                graph           = null;
                sourceBase      = null;
                mediaControl    = null;
                videoControl    = null;
                mediaEvent      = null;
                pinStillImage   = null;
                crossbar        = null;

                videoGrabberBase      = null;
                snapshotGrabberBase   = null;
                videoSampleGrabber    = null;
                snapshotSampleGrabber = null;

                if ( graphObject != null )
                {
                    Marshal.ReleaseComObject( graphObject );
                    graphObject = null;
                }
                if ( sourceObject != null )
                {
                    Marshal.ReleaseComObject( sourceObject );
                    sourceObject = null;
                }
                if ( videoGrabberObject != null )
                {
                    Marshal.ReleaseComObject( videoGrabberObject );
                    videoGrabberObject = null;
                }
                if ( snapshotGrabberObject != null )
                {
                    Marshal.ReleaseComObject( snapshotGrabberObject );
                    snapshotGrabberObject = null;
                }
                if ( captureGraphObject != null )
                {
                    Marshal.ReleaseComObject( captureGraphObject );
                    captureGraphObject = null;
                }
                if ( crossbarObject != null )
                {
                    Marshal.ReleaseComObject( crossbarObject );
                    crossbarObject = null;
                }
            }

            if ( PlayingFinished != null )
            {
                PlayingFinished( this, reasonToStop );
            }
        }
コード例 #2
0
ファイル: CaptureDevices.cs プロジェクト: Tob1112/405sentry
        // Thread entry point
        public void WorkerThread()
        {
            int hr;
            Guid cat;
            Guid med;

            // grabber
            Grabber grabber = new Grabber(this);

            // objects
            object graphObj = null;
            object grabberObj = null;

            // interfaces
            IGraphBuilder graphBuilder = null;
            ICaptureGraphBuilder2 captureGraphBuilder = null;
            IBaseFilter videoDeviceFilter = null;
            IBaseFilter grabberFilter = null;
            ISampleGrabber sg = null;
            IMediaControl mc = null;

            try
            {
                // Make a new filter graph
                graphObj = Activator.CreateInstance(
                Type.GetTypeFromCLSID(Clsid.FilterGraph, true));
                graphBuilder = (IGraphBuilder)graphObj;

                // Get the Capture Graph Builder
                Guid clsid = Clsid.CaptureGraphBuilder2;
                Guid riid = typeof(ICaptureGraphBuilder2).GUID;
                captureGraphBuilder = (ICaptureGraphBuilder2)
                TempFix.CreateDsInstance(ref clsid, ref riid);

                // Link the CaptureGraphBuilder to the filter graph
                hr = captureGraphBuilder.SetFiltergraph(graphBuilder);
                if (hr < 0) Marshal.ThrowExceptionForHR(hr);

                // Get the video device and add it to the filter graph
                if (source != null)
                {
                    videoDeviceFilter = (IBaseFilter)
                    Marshal.BindToMoniker(source);
                    hr = graphBuilder.AddFilter(videoDeviceFilter,
                    "Video Capture Device");
                    if (hr < 0) Marshal.ThrowExceptionForHR(hr);
                }

                // create sample grabber, object and filter
                grabberObj = Activator.CreateInstance(
                Type.GetTypeFromCLSID(Clsid.SampleGrabber, true));
                grabberFilter = (IBaseFilter)grabberObj;
                sg = (ISampleGrabber)grabberObj;

                // add sample grabber filter to filter graph
                hr = graphBuilder.AddFilter(grabberFilter, "grabber");
                if (hr < 0) Marshal.ThrowExceptionForHR(hr);

                // Try looking for an video device interleaved media type
                IBaseFilter testFilter = videoDeviceFilter;
                // grabberFilter (not supported)
                object o;
                cat = PinCategory.Capture;
                med = MediaType.Interleaved;
                Guid iid = typeof(IAMStreamConfig).GUID;
                hr = captureGraphBuilder.FindInterface(
                ref cat, ref med, testFilter, 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, testFilter, ref iid, out o);

                    if (hr != 0)
                        o = null;
                }
                // Set the video stream configuration to data member
                videoStreamConfig = o as IAMStreamConfig;
                o = null;

                // Experimental testing: Try to set the Frame Size & Rate
                // Results: When enabled, the grabber video breaks up into
                // several duplicate frames (6 frames)
                bool bdebug = true;
                if (bdebug)
                {
                    BitmapInfoHeader bmiHeader;
                    bmiHeader = (BitmapInfoHeader)
                    getStreamConfigSetting(videoStreamConfig, "BmiHeader");
                    bmiHeader.Width = framesize.Width;
                    bmiHeader.Height = framesize.Height;
                    setStreamConfigSetting(videoStreamConfig,
                    "BmiHeader", bmiHeader);

                    long avgTimePerFrame = (long)(10000000 / framerate);
                    setStreamConfigSetting(videoStreamConfig,
                    "AvgTimePerFrame", avgTimePerFrame);
                }

                // connect pins (Turns on the video device)
                if (graphBuilder.Connect(DSTools.GetOutPin(
                videoDeviceFilter, 0),
                DSTools.GetInPin(grabberFilter, 0)) < 0)
                    throw new ApplicationException(
                    "Failed connecting filters");

                // Set the sample grabber media type settings
                AMMediaType mt = new AMMediaType();
                mt.majorType = MediaType.Video;
                mt.subType = MediaSubType.RGB24;
                sg.SetMediaType(mt);

                // get media type
                if (sg.GetConnectedMediaType(mt) == 0)
                {
                    VideoInfoHeader vih = (VideoInfoHeader)Marshal.PtrToStructure(mt.formatPtr, typeof(VideoInfoHeader));
                    System.Diagnostics.Debug.WriteLine("width = " + vih.BmiHeader.Width + ", height = " + vih.BmiHeader.Height);
                    grabber.Width = vih.BmiHeader.Width;
                    grabber.Height = vih.BmiHeader.Height;
                    mt.Dispose();
                }

                // render
                graphBuilder.Render(DSTools.GetOutPin(grabberFilter, 0));

                // Set various sample grabber properties
                sg.SetBufferSamples(false);
                sg.SetOneShot(false);
                sg.SetCallback(grabber, 1);

                // Do not show active (source) window
                IVideoWindow win = (IVideoWindow)graphObj;
                win.put_AutoShow(false);
                win = null;

                // get media control
                mc = (IMediaControl)graphObj;

                // run
                mc.Run();

                while (!stopEvent.WaitOne(0, true))
                {
                    Thread.Sleep(100);
                }
                mc.StopWhenReady();
            }
            // catch any exceptions
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine("----: " + e.Message);
            }
            // finalization block
            finally
            {
                // release all objects
                mc = null;
                graphBuilder = null;
                captureGraphBuilder = null;
                videoDeviceFilter = null;
                grabberFilter = null;
                sg = null;

                if (graphObj != null)
                {
                    Marshal.ReleaseComObject(graphObj);
                    graphObj = null;
                }
                if (grabberObj != null)
                {
                    Marshal.ReleaseComObject(grabberObj);
                    grabberObj = null;
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// Worker thread.
        /// </summary>
        /// 
        private void WorkerThread( )
        {
            ReasonToFinishPlaying reasonToStop = ReasonToFinishPlaying.StoppedByUser;

            // grabber
            Grabber grabber = new Grabber( this );

            // objects
            object graphObject = null;
            object grabberObject = null;

            // interfaces
            IGraphBuilder       graph = null;
            IBaseFilter         sourceBase = null;
            IBaseFilter         grabberBase = null;
            ISampleGrabber      sampleGrabber = null;
            IMediaControl       mediaControl = null;

            IMediaEventEx       mediaEvent = null;

            try
            {
                // get type for filter graph
                Type type = Type.GetTypeFromCLSID( Clsid.FilterGraph );
                if ( type == null )
                    throw new ApplicationException( "Failed creating filter graph" );

                // create filter graph
                graphObject = Activator.CreateInstance( type );
                graph = (IGraphBuilder) graphObject;

                // create source device's object
                graph.AddSourceFilter( fileName, "source", out sourceBase );
                if ( sourceBase == null )
                    throw new ApplicationException( "Failed creating source filter" );

                // get type for sample grabber
                type = Type.GetTypeFromCLSID( Clsid.SampleGrabber );
                if ( type == null )
                    throw new ApplicationException( "Failed creating sample grabber" );

                // create sample grabber
                grabberObject = Activator.CreateInstance( type );
                sampleGrabber = (ISampleGrabber) grabberObject;
                grabberBase = (IBaseFilter) grabberObject;

                // add grabber filters to graph
                graph.AddFilter( grabberBase, "grabber" );

                // set media type
                AMMediaType mediaType = new AMMediaType( );
                mediaType.MajorType = MediaType.Video;
                mediaType.SubType = MediaSubType.RGB24;
                sampleGrabber.SetMediaType( mediaType );

                // connect pins
                int pinToTry = 0;

                IPin inPin = Tools.GetInPin( grabberBase, 0 );
                IPin outPin = null;

                // find output pin acceptable by sample grabber
                while ( true )
                {
                    outPin = Tools.GetOutPin( sourceBase, pinToTry );

                    if ( outPin == null )
                    {
                        Marshal.ReleaseComObject( inPin );
                        throw new ApplicationException( "Did not find acceptable output video pin in the given source" );
                    }

                    if ( graph.Connect( outPin, inPin ) < 0 )
                    {
                        Marshal.ReleaseComObject( outPin );
                        outPin = null;
                        pinToTry++;
                    }
                    else
                    {
                        break;
                    }
                }

                Marshal.ReleaseComObject( outPin );
                Marshal.ReleaseComObject( inPin );

                // get media type
                if ( sampleGrabber.GetConnectedMediaType( mediaType ) == 0 )
                {
                    VideoInfoHeader vih = (VideoInfoHeader) Marshal.PtrToStructure( mediaType.FormatPtr, typeof( VideoInfoHeader ) );

                    grabber.Width = vih.BmiHeader.Width;
                    grabber.Height = vih.BmiHeader.Height;
                    mediaType.Dispose( );
                }

                // let's do rendering, if we don't need to prevent freezing
                if ( !preventFreezing )
                {
                    // render pin
                    graph.Render( Tools.GetOutPin( grabberBase, 0 ) );

                    // configure video window
                    IVideoWindow window = (IVideoWindow) graphObject;
                    window.put_AutoShow( false );
                    window = null;
                }

                // configure sample grabber
                sampleGrabber.SetBufferSamples( false );
                sampleGrabber.SetOneShot( false );
                sampleGrabber.SetCallback( grabber, 1 );

                // disable clock, if someone requested it
                if ( !referenceClockEnabled )
                {
                    IMediaFilter mediaFilter = (IMediaFilter) graphObject;
                    mediaFilter.SetSyncSource( null );
                }

                // get media control
                mediaControl = (IMediaControl) graphObject;

                // get media events' interface
                mediaEvent = (IMediaEventEx) graphObject;
                IntPtr p1, p2;
                DsEvCode code;

                // run
                mediaControl.Run( );

                do
                {
                    if ( mediaEvent != null )
                    {
                        if ( mediaEvent.GetEvent( out code, out p1, out p2, 0 ) >= 0 )
                        {
                            mediaEvent.FreeEventParams( code, p1, p2 );

                            if ( code == DsEvCode.Complete )
                            {
                                reasonToStop = ReasonToFinishPlaying.EndOfStreamReached;
                                break;
                            }
                        }
                    }
                }
                while ( !stopEvent.WaitOne( 100, false ) );

                mediaControl.Stop( );
            }
            catch ( Exception exception )
            {
                // provide information to clients
                if ( VideoSourceError != null )
                {
                    VideoSourceError( this, new VideoSourceErrorEventArgs( exception.Message ) );
                }
            }
            finally
            {
                // release all objects
                graph           = null;
                grabberBase     = null;
                sampleGrabber   = null;
                mediaControl    = null;
                mediaEvent      = null;

                if ( graphObject != null )
                {
                    Marshal.ReleaseComObject( graphObject );
                    graphObject = null;
                }
                if ( sourceBase != null )
                {
                    Marshal.ReleaseComObject( sourceBase );
                    sourceBase = null;
                }
                if ( grabberObject != null )
                {
                    Marshal.ReleaseComObject( grabberObject );
                    grabberObject = null;
                }
            }

            if ( PlayingFinished != null )
            {
                PlayingFinished( this, reasonToStop );
            }
        }
コード例 #4
0
ファイル: VideoCaptureDevice.cs プロジェクト: pusp/o2platform
        private void WorkerThread( bool runGraph )
        {
            // grabber
            Grabber grabber = new Grabber( this );

            // objects
            object captureGraphObject = null;
            object graphObject = null;
            object grabberObject = null;

            // interfaces
            ICaptureGraphBuilder2 captureGraph = null;
            IFilterGraph2   graph = null;
            IBaseFilter     sourceBase = null;
            IBaseFilter     grabberBase = null;
            ISampleGrabber  sampleGrabber = null;
            IMediaControl   mediaControl = null;

            try
            {
                // get type of capture graph builder
                Type type = Type.GetTypeFromCLSID( Clsid.CaptureGraphBuilder2 );
                if ( type == null )
                    throw new ApplicationException( "Failed creating capture graph builder" );

                // create capture graph builder
                captureGraphObject = Activator.CreateInstance( type );
                captureGraph = (ICaptureGraphBuilder2) captureGraphObject;

                // get type of filter graph
                type = Type.GetTypeFromCLSID( Clsid.FilterGraph );
                if ( type == null )
                    throw new ApplicationException( "Failed creating filter graph" );

                // create filter graph
                graphObject = Activator.CreateInstance( type );
                graph = (IFilterGraph2) graphObject;

                // set filter graph to the capture graph builder
                captureGraph.SetFiltergraph( (IGraphBuilder) graph );

                // create source device's object
                sourceObject = FilterInfo.CreateFilter( deviceMoniker );
                if ( sourceObject == null )
                    throw new ApplicationException( "Failed creating device object for moniker" );

                // get base filter interface of source device
                sourceBase = (IBaseFilter) sourceObject;

                // get type of sample grabber
                type = Type.GetTypeFromCLSID( Clsid.SampleGrabber );
                if ( type == null )
                    throw new ApplicationException( "Failed creating sample grabber" );

                // create sample grabber
                grabberObject = Activator.CreateInstance( type );
                sampleGrabber = (ISampleGrabber) grabberObject;
                grabberBase = (IBaseFilter) grabberObject;

                // add source and grabber filters to graph
                graph.AddFilter( sourceBase, "source" );
                graph.AddFilter( grabberBase, "grabber" );

                // set media type
                AMMediaType mediaType = new AMMediaType( );
                mediaType.MajorType = MediaType.Video;
                mediaType.SubType   = MediaSubType.RGB24;

                sampleGrabber.SetMediaType( mediaType );

                // configure sample grabber
                sampleGrabber.SetBufferSamples( false );
                sampleGrabber.SetOneShot( false );
                sampleGrabber.SetCallback( grabber, 1 );

                // check if it is required to change capture settings
                if ( ( desiredFrameRate != 0 ) || ( ( desiredFrameSize.Width != 0 ) && ( desiredFrameSize.Height != 0 ) ) )
                {
                    object streamConfigObject;
                    // get stream configuration object
                    captureGraph.FindInterface( PinCategory.Capture, MediaType.Video, sourceBase, typeof( IAMStreamConfig ).GUID, out streamConfigObject );

                    if ( streamConfigObject != null )
                    {
                        IAMStreamConfig streamConfig = (IAMStreamConfig) streamConfigObject;

                        if ( videoCapabilities == null )
                        {
                            // get all video capabilities
                            try
                            {
                                videoCapabilities = AForge.Video.DirectShow.VideoCapabilities.FromStreamConfig( streamConfig );
                            }
                            catch
                            {
                            }
                        }

                        // get current format
                        streamConfig.GetFormat( out mediaType );
                        VideoInfoHeader infoHeader = (VideoInfoHeader) Marshal.PtrToStructure( mediaType.FormatPtr, typeof( VideoInfoHeader ) );

                        // change frame size if required
                        if ( ( desiredFrameSize.Width != 0 ) && ( desiredFrameSize.Height != 0 ) )
                        {
                            infoHeader.BmiHeader.Width = desiredFrameSize.Width;
                            infoHeader.BmiHeader.Height = desiredFrameSize.Height;
                        }
                        // change frame rate if required
                        if ( desiredFrameRate != 0 )
                        {
                            infoHeader.AverageTimePerFrame = 10000000 / desiredFrameRate;
                        }

                        // copy the media structure back
                        Marshal.StructureToPtr( infoHeader, mediaType.FormatPtr, false );

                        // set the new format
                        streamConfig.SetFormat( mediaType );

                        mediaType.Dispose( );
                    }
                }
                else
                {
                    if ( videoCapabilities == null )
                    {
                        object streamConfigObject;
                        // get stream configuration object
                        captureGraph.FindInterface( PinCategory.Capture, MediaType.Video, sourceBase, typeof( IAMStreamConfig ).GUID, out streamConfigObject );

                        if ( streamConfigObject != null )
                        {
                            IAMStreamConfig streamConfig = (IAMStreamConfig) streamConfigObject;
                            // get all video capabilities
                            try
                            {
                                videoCapabilities = AForge.Video.DirectShow.VideoCapabilities.FromStreamConfig( streamConfig );
                            }
                            catch
                            {
                            }
                        }
                    }
                }

                if ( runGraph )
                {
                    // render source device on sample grabber
                    captureGraph.RenderStream( PinCategory.Capture, MediaType.Video, sourceBase, null, grabberBase );

                    // get media type
                    if ( sampleGrabber.GetConnectedMediaType( mediaType ) == 0 )
                    {
                        VideoInfoHeader vih = (VideoInfoHeader) Marshal.PtrToStructure( mediaType.FormatPtr, typeof( VideoInfoHeader ) );

                        grabber.Width = vih.BmiHeader.Width;
                        grabber.Height = vih.BmiHeader.Height;
                        mediaType.Dispose( );
                    }

                    // get media control
                    mediaControl = (IMediaControl) graphObject;

                    // run
                    mediaControl.Run( );

                    while ( !stopEvent.WaitOne( 0, true ) )
                    {
                        Thread.Sleep( 100 );

                        if ( needToDisplayPropertyPage )
                        {
                            needToDisplayPropertyPage = false;

                            try
                            {
                                // retrieve ISpecifyPropertyPages interface of the device
                                ISpecifyPropertyPages pPropPages = (ISpecifyPropertyPages) sourceObject;

                                // get property pages from the property bag
                                CAUUID caGUID;
                                pPropPages.GetPages( out caGUID );

                                // get filter info
                                FilterInfo filterInfo = new FilterInfo( deviceMoniker );

                                // create and display the OlePropertyFrame
                                Win32.OleCreatePropertyFrame( parentWindowForPropertyPage, 0, 0, filterInfo.Name, 1, ref sourceObject, caGUID.cElems, caGUID.pElems, 0, 0, IntPtr.Zero );

                                // release COM objects
                                Marshal.FreeCoTaskMem( caGUID.pElems );
                            }
                            catch
                            {
                            }
                        }
                    }
                    mediaControl.StopWhenReady( );
                }
            }
            catch ( Exception exception )
            {
                // provide information to clients
                if ( VideoSourceError != null )
                {
                    VideoSourceError( this, new VideoSourceErrorEventArgs( exception.Message ) );
                }
            }
            finally
            {
                // release all objects
                captureGraph    = null;
                graph           = null;
                sourceBase      = null;
                grabberBase     = null;
                sampleGrabber   = null;
                mediaControl    = null;

                if ( graphObject != null )
                {
                    Marshal.ReleaseComObject( graphObject );
                    graphObject = null;
                }
                if ( sourceObject != null )
                {
                    Marshal.ReleaseComObject( sourceObject );
                    sourceObject = null;
                }
                if ( grabberObject != null )
                {
                    Marshal.ReleaseComObject( grabberObject );
                    grabberObject = null;
                }
                if ( captureGraphObject != null )
                {
                    Marshal.ReleaseComObject( captureGraphObject );
                    captureGraphObject = null;
                }
            }

            if ( PlayingFinished != null )
            {
                PlayingFinished( this, ReasonToFinishPlaying.StoppedByUser );
            }
        }