Example #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, videoResolution, ref videoCapabilities );
                if ( isSapshotSupported )
                {
                    GetPinCapabilitiesAndConfigureSizeAndRate( captureGraph, sourceBase,
                        PinCategory.StillImage, snapshotResolution, 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 );
            }
        }
Example #2
0
        // Set type of input connected to video output of the crossbar
        private void SetCurrentCrossbarInput( IAMCrossbar crossbar, VideoInput videoInput )
        {
            if ( videoInput.Type != PhysicalConnectorType.Default )
            {
                int inPinsCount, outPinsCount;

                // gen number of pins in the crossbar
                if ( crossbar.get_PinCounts( out outPinsCount, out inPinsCount ) == 0 )
                {
                    int videoOutputPinIndex = -1;
                    int videoInputPinIndex = -1;
                    int pinIndexRelated;
                    PhysicalConnectorType type;

                    // find index of the video output pin
                    for ( int i = 0; i < outPinsCount; i++ )
                    {
                        if ( crossbar.get_CrossbarPinInfo( false, i, out pinIndexRelated, out type ) != 0 )
                            continue;

                        if ( type == PhysicalConnectorType.VideoDecoder )
                        {
                            videoOutputPinIndex = i;
                            break;
                        }
                    }

                    // find index of the required input pin
                    for ( int i = 0; i < inPinsCount; i++ )
                    {
                        if ( crossbar.get_CrossbarPinInfo( true, i, out pinIndexRelated, out type ) != 0 )
                            continue;

                        if ( ( type == videoInput.Type ) && ( i == videoInput.Index ) )
                        {
                            videoInputPinIndex = i;
                            break;
                        }
                    }

                    // try connecting pins
                    if ( ( videoInputPinIndex != -1 ) && ( videoOutputPinIndex != -1 ) &&
                         ( crossbar.CanRoute( videoOutputPinIndex, videoInputPinIndex ) == 0 ) )
                    {
                        crossbar.Route( videoOutputPinIndex, videoInputPinIndex );
                    }
                }
            }
        }
Example #3
0
        // Collect all video inputs of the specified crossbar
        private VideoInput[] ColletCrossbarVideoInputs( IAMCrossbar crossbar )
        {
            lock ( cacheCrossbarVideoInputs )
            {
                if ( cacheCrossbarVideoInputs.ContainsKey( deviceMoniker ) )
                {
                    return cacheCrossbarVideoInputs[deviceMoniker];
                }

                List<VideoInput> videoInputsList = new List<VideoInput>( );

                if ( crossbar != null )
                {
                    int inPinsCount, outPinsCount;

                    // gen number of pins in the crossbar
                    if ( crossbar.get_PinCounts( out outPinsCount, out inPinsCount ) == 0 )
                    {
                        // collect all video inputs
                        for ( int i = 0; i < inPinsCount; i++ )
                        {
                            int pinIndexRelated;
                            PhysicalConnectorType type;

                            if ( crossbar.get_CrossbarPinInfo( true, i, out pinIndexRelated, out type ) != 0 )
                                continue;

                            if ( type < PhysicalConnectorType.AudioTuner )
                            {
                                videoInputsList.Add( new VideoInput( i, type ) );
                            }
                        }
                    }
                }

                VideoInput[] videoInputs = new VideoInput[videoInputsList.Count];
                videoInputsList.CopyTo( videoInputs );

                cacheCrossbarVideoInputs.Add( deviceMoniker, videoInputs );

                return videoInputs;
            }
        }
Example #4
0
        // Get type of input connected to video output of the crossbar
        private VideoInput GetCurrentCrossbarInput( IAMCrossbar crossbar )
        {
            VideoInput videoInput = VideoInput.Default;

            int inPinsCount, outPinsCount;

            // gen number of pins in the crossbar
            if ( crossbar.get_PinCounts( out outPinsCount, out inPinsCount ) == 0 )
            {
                int videoOutputPinIndex = -1;
                int pinIndexRelated;
                PhysicalConnectorType type;

                // find index of the video output pin
                for ( int i = 0; i < outPinsCount; i++ )
                {
                    if ( crossbar.get_CrossbarPinInfo( false, i, out pinIndexRelated, out type ) != 0 )
                        continue;

                    if ( type == PhysicalConnectorType.VideoDecoder )
                    {
                        videoOutputPinIndex = i;
                        break;
                    }
                }

                if ( videoOutputPinIndex != -1 )
                {
                    int videoInputPinIndex;

                    // get index of the input pin connected to the output
                    if ( crossbar.get_IsRoutedTo( videoOutputPinIndex, out videoInputPinIndex ) == 0 )
                    {
                        PhysicalConnectorType inputType;

                        crossbar.get_CrossbarPinInfo( true, videoInputPinIndex, out pinIndexRelated, out inputType );

                        videoInput = new VideoInput( videoInputPinIndex, inputType );
                    }
                }
            }

            return videoInput;
        }
        // Ok button clicked
        private void okButton_Click( object sender, EventArgs e )
        {
            videoDeviceMoniker = videoDevice.Source;

            // set video size
            if ( videoCapabilitiesDictionary.Count != 0 )
            {
                VideoCapabilities caps = videoCapabilitiesDictionary[(string) videoResolutionsCombo.SelectedItem];

                videoDevice.VideoResolution = caps;
                captureSize = caps.FrameSize;
            }

            if ( configureSnapshots )
            {
                // set snapshots size
                if ( snapshotCapabilitiesDictionary.Count != 0 )
                {
                    VideoCapabilities caps = snapshotCapabilitiesDictionary[(string) snapshotResolutionsCombo.SelectedItem];

                    videoDevice.ProvideSnapshots = true;
                    videoDevice.SnapshotResolution = caps;

                    snapshotSize = caps.FrameSize;
                }
            }

            if ( availableVideoInputs.Length != 0 )
            {
                videoInput = availableVideoInputs[videoInputsCombo.SelectedIndex];
                videoDevice.CrossbarVideoInput = videoInput;
            }
        }