/// <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 ); } }
private void WorkerThread(bool runGraph) { ReasonToFinishPlaying reasonToStop = ReasonToFinishPlaying.StoppedByUser; bool isSnapshotSupported = false; // grabber Grabber videoGrabber = new Grabber(this, false, this.pixelFormat); Grabber snapshotGrabber = new Grabber(this, true, this.pixelFormat); // 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.ConvertFrom(pixelFormat); 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 video 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); isSnapshotSupported = ((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 (isSnapshotSupported) { 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 ((isSnapshotSupported) && (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 ((isSnapshotSupported) && (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 ((isSnapshotSupported) && (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); } }