private void RaiseVideoSourceFinishedEvent(VideoSourceFinishedReasonType reason) { if (VideoSourceFinished != null) { VideoSourceFinished(this, new VideoSourceFinishedEventArgs(reason)); } }
/// <summary> /// 视频源视频结束事件参数 /// </summary> /// <param name="reason">视频源视频结束原因</param> public VideoSourceFinishedEventArgs(VideoSourceFinishedReasonType reason) { this.reason = reason; }
/// <summary> /// 工作线程 /// </summary> private void WorkerThread() { VideoSourceFinishedReasonType reasonToStop = VideoSourceFinishedReasonType.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 VideoSourceException("Failed creating filter graph"); } // create filter graph graphObject = Activator.CreateInstance(type); graph = (IGraphBuilder)graphObject; // create source device's object graph.AddSourceFilter(Source, "source", out sourceBase); if (sourceBase == null) { throw new VideoSourceException("Failed creating source filter"); } // get type for sample grabber type = Type.GetTypeFromCLSID(Clsid.SampleGrabber); if (type == null) { throw new VideoSourceException("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 = PinHelper.GetInPin(grabberBase, 0); IPin outPin = null; // find output pin acceptable by sample grabber while (true) { outPin = PinHelper.GetOutPin(sourceBase, pinToTry); if (outPin == null) { Marshal.ReleaseComObject(inPin); throw new VideoSourceException("Cannot 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(PinHelper.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(); while (!stopEvent.WaitOne(0, false)) { Thread.Sleep(100); if (mediaEvent != null) { if (mediaEvent.GetEvent(out code, out p1, out p2, 0) >= 0) { mediaEvent.FreeEventParams(code, p1, p2); if (code == DsEvCode.Complete) { reasonToStop = VideoSourceFinishedReasonType.EndOfStreamReached; break; } } } } // stop mediaControl.Stop(); } catch (Exception ex) { // provide information to clients if (VideoSourceException != null) { VideoSourceException(this, new VideoSourceExceptionEventArgs(ex.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 (VideoSourceFinished != null) { VideoSourceFinished(this, new VideoSourceFinishedEventArgs(reasonToStop)); } }
/// <summary> /// 触发视频源结束事件 /// </summary> /// <param name="reason">视频源结束原因</param> protected void RaiseVideoSourceFinishedEvent(VideoSourceFinishedReasonType reason) { if (VideoSourceFinished != null) { VideoSourceFinished(this, new VideoSourceFinishedEventArgs(reason)); } }
/// <summary> /// Worker thread. /// </summary> /// private void WorkerThread() { VideoSourceFinishedReasonType reasonToStop = VideoSourceFinishedReasonType.StoppedByUser; // AVI reader AVIReader aviReader = new AVIReader(); try { // open file aviReader.Open(source); // stop positions int stopPosition = aviReader.Start + aviReader.Length; // frame interval int interval = (frameIntervalFromSource) ? (int)(1000 / aviReader.FrameRate) : frameInterval; while (!stopEvent.WaitOne(0, false)) { // start time DateTime start = DateTime.Now; // get next frame Bitmap bitmap = aviReader.GetNextFrame(); framesReceived++; if (NewFrame != null) { NewFrame(this, new NewFrameEventArgs(bitmap, DateTime.Now)); } // free image bitmap.Dispose(); // check current position if (aviReader.Position >= stopPosition) { reasonToStop = VideoSourceFinishedReasonType.EndOfStreamReached; break; } // wait for a while ? if (interval > 0) { // get frame extract duration TimeSpan span = DateTime.Now.Subtract(start); // miliseconds to sleep int msec = interval - (int)span.TotalMilliseconds; while ((msec > 0) && (stopEvent.WaitOne(0, true) == false)) { // sleeping ... Thread.Sleep((msec < 100) ? msec : 100); msec -= 100; } } } } catch (Exception ex) { // provide information to clients if (VideoSourceException != null) { VideoSourceException(this, new VideoSourceExceptionEventArgs(ex.Message)); } } aviReader.Dispose(); aviReader = null; if (VideoSourceFinished != null) { VideoSourceFinished(this, new VideoSourceFinishedEventArgs(reasonToStop)); } }
private void WorkerThread(bool runGraph) { VideoSourceFinishedReasonType reasonToStop = VideoSourceFinishedReasonType.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; // 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; 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); 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]; } 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); } while (!stopEvent.WaitOne(0, false)) { Thread.Sleep(100); if (mediaEvent != null) { if (mediaEvent.GetEvent(out code, out p1, out p2, 0) >= 0) { mediaEvent.FreeEventParams(code, p1, p2); if (code == DsEvCode.DeviceLost) { reasonToStop = VideoSourceFinishedReasonType.DeviceLost; break; } } } if (needToSimulateTrigger) { needToSimulateTrigger = false; if ((isSapshotSupported) && (provideSnapshots)) { videoControl.SetMode(pinStillImage, VideoControlFlags.Trigger); } } 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.Stop(); } } catch (Exception exception) { // provide information to clients if (VideoSourceException != null) { VideoSourceException(this, new VideoSourceExceptionEventArgs(exception.Message)); } } finally { // release all objects captureGraph = null; graph = null; sourceBase = null; mediaControl = null; videoControl = null; mediaEvent = null; pinStillImage = 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 (VideoSourceFinished != null) { VideoSourceFinished(this, new VideoSourceFinishedEventArgs(reasonToStop)); } }