void BuildGraph() { int hr; IBaseFilter ppFilter; DsDevice [] devs; IGraphBuilder graphBuilder = new FilterGraph() as IGraphBuilder; m_ROT = new DsROTEntry(graphBuilder); IFilterGraph2 ifg2 = graphBuilder as IFilterGraph2; devs = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); DsDevice dev = devs[0]; hr = ifg2.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out ppFilter); DsError.ThrowExceptionForHR(hr); m_ivc = ppFilter as IAMVideoControl; m_IPinOut = DsFindPin.ByDirection(ppFilter, PinDirection.Output, 0); hr = ifg2.Render(m_IPinOut); DsError.ThrowExceptionForHR(hr); m_imc = graphBuilder as IMediaControl; //hr = m_imc.Run(); DsError.ThrowExceptionForHR(hr); }
/// <summary> Shut down capture </summary> private void CloseInterfaces() { int hr; try { if (m_FilterGraph != null) { IMediaControl mediaCtrl = m_FilterGraph as IMediaControl; // Stop the graph hr = mediaCtrl.Stop(); } } catch (Exception ex) { Debug.WriteLine(ex); } if (m_FilterGraph != null) { Marshal.ReleaseComObject(m_FilterGraph); m_FilterGraph = null; } if (m_VidControl != null) { Marshal.ReleaseComObject(m_VidControl); m_VidControl = null; } if (m_pinStill != null) { Marshal.ReleaseComObject(m_pinStill); m_pinStill = null; } }
/// <summary> /// Set the Framerate, and video size /// </summary> /// <param name="capGraph">The <see cref="ICaptureGraphBuilder2"/> interface.</param> /// <param name="capFilter">The <see cref="IBaseFilter"/> of the capture device.</param> /// <param name="frameRate">The new framerate to be used.</param> /// <param name="width">The new video width to be used.</param> /// <param name="height">The new video height to be used.</param> private void SetConfigParms(ICaptureGraphBuilder2 capGraph, IBaseFilter capFilter, int frameRate, int width, int height) { int hr; object o; AMMediaType media; // Find the stream config interface hr = this.capGraph.FindInterface(PinCategory.Capture, MediaType.Video, capFilter, typeof(IAMStreamConfig).GUID, out o); this.videoControl = capFilter as IAMVideoControl; this.videoStreamConfig = o as IAMStreamConfig; if (this.videoStreamConfig == null) { ErrorLogger.WriteLine("Error in Capture.SetConfigParams(). Failed to get IAMStreamConfig"); } // Get the existing format block hr = this.videoStreamConfig.GetFormat(out media); if (hr != 0) { ErrorLogger.WriteLine("Could not SetConfigParms in Camera.Capture. Message: " + DsError.GetErrorText(hr)); } // copy out the videoinfoheader VideoInfoHeader v = new VideoInfoHeader(); Marshal.PtrToStructure(media.formatPtr, v); // if overriding set values if (frameRate > 0) { v.AvgTimePerFrame = 10000000 / frameRate; } if (width > 0) { v.BmiHeader.Width = width; } if (height > 0) { v.BmiHeader.Height = height; } // Copy the media structure back Marshal.StructureToPtr(v, media.formatPtr, true); // Set the new format hr = this.videoStreamConfig.SetFormat(media); if (hr != 0) { ErrorLogger.WriteLine("Error while setting new camera format (videoStreamConfig) in Camera.Capture. Message: " + DsError.GetErrorText(hr)); } DsUtils.FreeAMMediaType(media); media = null; }
/** * 必要に応じてグラフオブジェクトを全て削除する。 */ private void CleanupGraphiObjects() { this.m_video_info = null; if (m_FilterGraph != null) { Marshal.ReleaseComObject(m_FilterGraph); m_FilterGraph = null; } if (m_VidControl != null) { Marshal.ReleaseComObject(m_VidControl); m_VidControl = null; } if (m_pinStill != null) { Marshal.ReleaseComObject(m_pinStill); m_pinStill = null; } }
void BuildGraph() { int hr; IBaseFilter ppFilter; DsDevice [] devs; IGraphBuilder graphBuilder = new FilterGraph() as IGraphBuilder; m_ROT = new DsROTEntry(graphBuilder); IFilterGraph2 ifg2 = graphBuilder as IFilterGraph2; devs = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); DsDevice dev = devs[0]; hr = ifg2.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out ppFilter); DsError.ThrowExceptionForHR(hr); m_ivc = ppFilter as IAMVideoControl; m_IPinOut = DsFindPin.ByDirection(ppFilter, PinDirection.Output, 0); hr = ifg2.Render(m_IPinOut); DsError.ThrowExceptionForHR(hr); ICaptureGraphBuilder2 captureGraphBuilder = new CaptureGraphBuilder2() as ICaptureGraphBuilder2; hr = captureGraphBuilder.SetFiltergraph(graphBuilder); object o; hr = captureGraphBuilder.FindInterface(null, null, ppFilter, typeof(IAMAnalogVideoDecoder).GUID, out o); DsError.ThrowExceptionForHR(hr); m_avd = o as IAMAnalogVideoDecoder; m_imc = graphBuilder as IMediaControl; hr = m_imc.Run(); DsError.ThrowExceptionForHR(hr); }
public static void FixFlippedVideo(IAMVideoControl videoControl, IPin pPin) { VideoControlFlags pCapsFlags; int hr = videoControl.GetCaps(pPin, out pCapsFlags); DsError.ThrowExceptionForHR(hr); if ((pCapsFlags & VideoControlFlags.FlipVertical) > 0) { hr = videoControl.GetMode(pPin, out pCapsFlags); DsError.ThrowExceptionForHR(hr); hr = videoControl.SetMode(pPin, pCapsFlags & ~VideoControlFlags.FlipVertical); DsError.ThrowExceptionForHR(hr); PinInfo pinInfo; hr = pPin.QueryPinInfo(out pinInfo); DsError.ThrowExceptionForHR(hr); Trace.WriteLine("Fixing 'FlipVertical' video for pin " + pinInfo.name); } if ((pCapsFlags & VideoControlFlags.FlipHorizontal) > 0) { hr = videoControl.GetMode(pPin, out pCapsFlags); DsError.ThrowExceptionForHR(hr); hr = videoControl.SetMode(pPin, pCapsFlags | VideoControlFlags.FlipHorizontal); DsError.ThrowExceptionForHR(hr); PinInfo pinInfo; hr = pPin.QueryPinInfo(out pinInfo); DsError.ThrowExceptionForHR(hr); Trace.WriteLine("Fixing 'FlipHorizontal' video for pin " + pinInfo.name); } }
public override void Cleanup() { try { // To stop the capture filter before stopping the media control // seems to solve the problem described in the next comment. // sancta simplicitas... if (capFilter != null) { capFilter.Stop(); } // The stop or stopwhenready methods sometimes hang ... // This is a multithreading issue but I don´t solved it yet // But stopping is needed, otherwise the video device // is not disposed fast enough (due to GC) so at next initialization // with other params the video device seems to be in // use and the GraphBuilder render mehtod fails. if (mediaControl != null) { // This hangs when closing the GT int hr = mediaControl.Stop(); } isRunning = false; } catch (Exception ex) { //ErrorLogger.ProcessException(ex, false); Console.WriteLine("ERROR! " + ex.ToString()); MessageBox.Show(ex.Message); } if (capFilter != null) { Marshal.ReleaseComObject(capFilter); capFilter = null; cameraControl = null; videoControl = null; videoStreamConfig = null; } if (videoProcAmp != null) { Marshal.ReleaseComObject(videoProcAmp); videoProcAmp = null; } if (sampGrabber != null) { Marshal.ReleaseComObject(sampGrabber); sampGrabber = null; } if (graphBuilder != null) { Marshal.ReleaseComObject(graphBuilder); graphBuilder = null; mediaControl = null; hasValidGraph = false; } if (capGraph != null) { Marshal.ReleaseComObject(capGraph); capGraph = null; } if (map != IntPtr.Zero) { UnmapViewOfFile(map); map = IntPtr.Zero; } if (section != IntPtr.Zero) { CloseHandle(section); section = IntPtr.Zero; } #if DEBUG if (this.rotEntry != null) { // This hangs when closing the GT this.rotEntry.Dispose(); } #endif }
private void WorkerThread(bool runGraph) { ReasonToFinishPlaying reasonToStop = ReasonToFinishPlaying.StoppedByUser; bool isSapshotSupported = false; Grabber videoGrabber = new Grabber(this, false); Grabber snapshotGrabber = new Grabber(this, true); object captureGraphObject = null; object graphObject = null; object videoGrabberObject = null; object snapshotGrabberObject = null; object crossbarObject = null; 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 { Type type = Type.GetTypeFromCLSID(Clsid.CaptureGraphBuilder2); if (type == null) { throw new ApplicationException("Failed creating capture graph builder"); } captureGraphObject = Activator.CreateInstance(type); captureGraph = (ICaptureGraphBuilder2)captureGraphObject; type = Type.GetTypeFromCLSID(Clsid.FilterGraph); if (type == null) { throw new ApplicationException("Failed creating filter graph"); } graphObject = Activator.CreateInstance(type); graph = (IFilterGraph2)graphObject; captureGraph.SetFiltergraph((IGraphBuilder)graph); sourceObject = FilterInfo.CreateFilter(deviceMoniker); if (sourceObject == null) { throw new ApplicationException("Failed creating device object for moniker"); } sourceBase = (IBaseFilter)sourceObject; try { videoControl = (IAMVideoControl)sourceObject; } catch { } type = Type.GetTypeFromCLSID(Clsid.SampleGrabber); if (type == null) { throw new ApplicationException("Failed creating sample grabber"); } videoGrabberObject = Activator.CreateInstance(type); videoSampleGrabber = (ISampleGrabber)videoGrabberObject; videoGrabberBase = (IBaseFilter)videoGrabberObject; snapshotGrabberObject = Activator.CreateInstance(type); snapshotSampleGrabber = (ISampleGrabber)snapshotGrabberObject; snapshotGrabberBase = (IBaseFilter)snapshotGrabberObject; graph.AddFilter(sourceBase, "source"); graph.AddFilter(videoGrabberBase, "grabber_video"); graph.AddFilter(snapshotGrabberBase, "grabber_snapshot"); AMMediaType mediaType = new AMMediaType( ); mediaType.MajorType = MediaType.Video; mediaType.SubType = MediaSubType.RGB24; videoSampleGrabber.SetMediaType(mediaType); snapshotSampleGrabber.SetMediaType(mediaType); 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) { captureGraph.FindPin(sourceObject, PinDirection.Output, PinCategory.StillImage, MediaType.Video, false, 0, out pinStillImage); if (pinStillImage != null) { VideoControlFlags caps; videoControl.GetCaps(pinStillImage, out caps); isSapshotSupported = ((caps & VideoControlFlags.ExternalTriggerEnable) != 0); } } videoSampleGrabber.SetBufferSamples(false); videoSampleGrabber.SetOneShot(false); videoSampleGrabber.SetCallback(videoGrabber, 1); snapshotSampleGrabber.SetBufferSamples(true); snapshotSampleGrabber.SetOneShot(false); snapshotSampleGrabber.SetCallback(snapshotGrabber, 1); GetPinCapabilitiesAndConfigureSizeAndRate(captureGraph, sourceBase, PinCategory.Capture, videoResolution, ref videoCapabilities); if (isSapshotSupported) { GetPinCapabilitiesAndConfigureSizeAndRate(captureGraph, sourceBase, PinCategory.StillImage, snapshotResolution, ref snapshotCapabilities); } else { snapshotCapabilities = new VideoCapabilities[0]; } 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) { 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)) { 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( ); } } mediaControl = (IMediaControl)graphObject; mediaEvent = (IMediaEventEx)graphObject; IntPtr p1, p2; DsEvCode code; 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; 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) { if (VideoSourceError != null) { VideoSourceError(this, new VideoSourceErrorEventArgs(exception.Message)); } } finally { 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); } }
private static void DoSupportedVideoFormatsOperation(string deviceName, SupportedVideoFormatCallback callback) { IGraphBuilder graphBuilder = null; ICaptureGraphBuilder2 captureGraphBuilder = null; IBaseFilter theDevice = null; try { graphBuilder = (IGraphBuilder) new FilterGraph(); captureGraphBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); theDevice = CreateFilter(FilterCategory.VideoInputDevice, deviceName); // Attach the filter graph to the capture graph int hr = captureGraphBuilder.SetFiltergraph(graphBuilder); DsError.ThrowExceptionForHR(hr); // Add the Video input device to the graph hr = graphBuilder.AddFilter(theDevice, "source filter"); DsError.ThrowExceptionForHR(hr); object o; // AMMediaType media; IAMStreamConfig videoStreamConfig; IAMVideoControl videoControl = theDevice as IAMVideoControl; hr = captureGraphBuilder.FindInterface(PinCategory.Capture, MediaType.Video, theDevice, typeof(IAMStreamConfig).GUID, out o); DsError.ThrowExceptionForHR(hr); videoStreamConfig = o as IAMStreamConfig; try { if (videoStreamConfig == null) { throw new Exception("Failed to get IAMStreamConfig"); } int iCount = 0, iSize = 0; videoStreamConfig.GetNumberOfCapabilities(out iCount, out iSize); IntPtr taskMemPointer = Marshal.AllocCoTaskMem(iSize); AMMediaType pmtConfig = null; for (int iFormat = 0; iFormat < iCount; iFormat++) { IntPtr ptr = IntPtr.Zero; videoStreamConfig.GetStreamCaps(iFormat, out pmtConfig, taskMemPointer); var v2 = (VideoInfoHeader)Marshal.PtrToStructure(pmtConfig.formatPtr, typeof(VideoInfoHeader)); if (v2.BmiHeader.BitCount > 0) { var entry = new SupportedVideoFormat() { Width = v2.BmiHeader.Width, Height = v2.BmiHeader.Height, BitCount = v2.BmiHeader.BitCount, FrameRate = 10000000.0 / v2.AvgTimePerFrame }; callback(entry); Trace.WriteLine(entry.AsSerialized()); } } Marshal.FreeCoTaskMem(taskMemPointer); DsUtils.FreeAMMediaType(pmtConfig); } finally { Marshal.ReleaseComObject(videoStreamConfig); } } finally { if (theDevice != null) { Marshal.ReleaseComObject(theDevice); } if (graphBuilder != null) { Marshal.ReleaseComObject(graphBuilder); } if (captureGraphBuilder != null) { Marshal.ReleaseComObject(captureGraphBuilder); } } }
// Token: 0x0600003F RID: 63 RVA: 0x00002D24 File Offset: 0x00000F24 private void WorkerThread(bool runGraph) { ReasonToFinishPlaying reason = ReasonToFinishPlaying.StoppedByUser; bool flag = false; VideoCaptureDevice.Grabber grabber = new VideoCaptureDevice.Grabber(this, false); VideoCaptureDevice.Grabber grabber2 = new VideoCaptureDevice.Grabber(this, true); object obj = null; object obj2 = null; object obj3 = null; object obj4 = null; object obj5 = null; ICaptureGraphBuilder2 captureGraphBuilder = null; IFilterGraph2 filterGraph = null; IBaseFilter baseFilter = null; IBaseFilter baseFilter2 = null; IBaseFilter baseFilter3 = null; ISampleGrabber sampleGrabber = null; ISampleGrabber sampleGrabber2 = null; IAMVideoControl iamvideoControl = null; IPin pin = null; IAMCrossbar iamcrossbar = null; try { Type typeFromCLSID = Type.GetTypeFromCLSID(Clsid.CaptureGraphBuilder2); if (typeFromCLSID == null) { throw new ApplicationException("Failed creating capture graph builder"); } obj = Activator.CreateInstance(typeFromCLSID); captureGraphBuilder = (ICaptureGraphBuilder2)obj; Type typeFromCLSID2 = Type.GetTypeFromCLSID(Clsid.FilterGraph); if (typeFromCLSID2 == null) { throw new ApplicationException("Failed creating filter graph"); } obj2 = Activator.CreateInstance(typeFromCLSID2); filterGraph = (IFilterGraph2)obj2; captureGraphBuilder.SetFiltergraph((IGraphBuilder)filterGraph); this.sourceObject1 = FilterInfo.CreateFilter(this.deviceMoniker1); if (this.sourceObject1 == null) { throw new ApplicationException("Failed creating device object for moniker"); } baseFilter = (IBaseFilter)this.sourceObject1; try { iamvideoControl = (IAMVideoControl)this.sourceObject1; } catch { } Type typeFromCLSID3 = Type.GetTypeFromCLSID(Clsid.SampleGrabber); if (typeFromCLSID3 == null) { throw new ApplicationException("Failed creating sample grabber"); } obj3 = Activator.CreateInstance(typeFromCLSID3); sampleGrabber = (ISampleGrabber)obj3; baseFilter2 = (IBaseFilter)obj3; obj4 = Activator.CreateInstance(typeFromCLSID3); sampleGrabber2 = (ISampleGrabber)obj4; baseFilter3 = (IBaseFilter)obj4; filterGraph.AddFilter(baseFilter, "source"); filterGraph.AddFilter(baseFilter2, "grabber_video"); filterGraph.AddFilter(baseFilter3, "grabber_snapshot"); AMMediaType ammediaType = new AMMediaType(); ammediaType.MajorType = MediaType.Video1; ammediaType.SubType = MediaSubType.RGB24; sampleGrabber.SetMediaType(ammediaType); sampleGrabber2.SetMediaType(ammediaType); captureGraphBuilder.FindInterface(FindDirection.UpstreamOnly, Guid.Empty, baseFilter, typeof(IAMCrossbar).GUID, out obj5); if (obj5 != null) { iamcrossbar = (IAMCrossbar)obj5; } this.isCrossbarAvailable1 = new bool?(iamcrossbar != null); this.crossbarVideoInputs1 = this.ColletCrossbarVideoInputs(iamcrossbar); if (iamvideoControl != null) { captureGraphBuilder.FindPin(this.sourceObject1, PinDirection.Output, PinCategory.StillImage, MediaType.Video1, false, 0, out pin); if (pin != null) { VideoControlFlags videoControlFlags; iamvideoControl.GetCaps(pin, out videoControlFlags); flag = ((videoControlFlags & VideoControlFlags.ExternalTriggerEnable) > (VideoControlFlags)0); } } sampleGrabber.SetBufferSamples(false); sampleGrabber.SetOneShot(false); sampleGrabber.SetCallback(grabber, 1); sampleGrabber2.SetBufferSamples(true); sampleGrabber2.SetOneShot(false); sampleGrabber2.SetCallback(grabber2, 1); this.GetPinCapabilitiesAndConfigureSizeAndRate(captureGraphBuilder, baseFilter, PinCategory.Capture, this.videoResolution1, ref this.videoCapabilities1); if (flag) { this.GetPinCapabilitiesAndConfigureSizeAndRate(captureGraphBuilder, baseFilter, PinCategory.StillImage, this.snapshotResolution1, ref this.snapshotCapabilities1); } else { this.snapshotCapabilities1 = new VideoCapabilities[0]; } Dictionary <string, VideoCapabilities[]> obj6 = VideoCaptureDevice.cacheVideoCapabilities1; lock (obj6) { if (this.videoCapabilities1 != null && !VideoCaptureDevice.cacheVideoCapabilities1.ContainsKey(this.deviceMoniker1)) { VideoCaptureDevice.cacheVideoCapabilities1.Add(this.deviceMoniker1, this.videoCapabilities1); } } obj6 = VideoCaptureDevice.cacheSnapshotCapabilities1; lock (obj6) { if (this.snapshotCapabilities1 != null && !VideoCaptureDevice.cacheSnapshotCapabilities1.ContainsKey(this.deviceMoniker1)) { VideoCaptureDevice.cacheSnapshotCapabilities1.Add(this.deviceMoniker1, this.snapshotCapabilities1); } } if (runGraph) { captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Video1, baseFilter, null, baseFilter2); if (sampleGrabber.GetConnectedMediaType(ammediaType) == 0) { VideoInfoHeader videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(ammediaType.FormatPtr, typeof(VideoInfoHeader)); grabber.Width = videoInfoHeader.BmiHeader.Width; grabber.Height = videoInfoHeader.BmiHeader.Height; ammediaType.Dispose(); } if (flag && this.provideSnapshots1) { captureGraphBuilder.RenderStream(PinCategory.StillImage, MediaType.Video1, baseFilter, null, baseFilter3); if (sampleGrabber2.GetConnectedMediaType(ammediaType) == 0) { VideoInfoHeader videoInfoHeader2 = (VideoInfoHeader)Marshal.PtrToStructure(ammediaType.FormatPtr, typeof(VideoInfoHeader)); grabber2.Width = videoInfoHeader2.BmiHeader.Width; grabber2.Height = videoInfoHeader2.BmiHeader.Height; ammediaType.Dispose(); } } IMediaControl mediaControl = (IMediaControl)obj2; IMediaEventEx mediaEventEx = (IMediaEventEx)obj2; mediaControl.Run(); if (flag && this.provideSnapshots1) { this.startTime1 = DateTime.Now; iamvideoControl.SetMode(pin, VideoControlFlags.ExternalTriggerEnable); } for (;;) { DsEvCode dsEvCode; IntPtr lParam; IntPtr lParam2; if (mediaEventEx != null && mediaEventEx.GetEvent(out dsEvCode, out lParam, out lParam2, 0) >= 0) { mediaEventEx.FreeEventParams(dsEvCode, lParam, lParam2); if (dsEvCode == DsEvCode.DeviceLost) { break; } } if (this.needToSetVideoInput1) { this.needToSetVideoInput1 = false; if (this.isCrossbarAvailable1.Value) { this.SetCurrentCrossbarInput(iamcrossbar, this.crossbarVideoInput1); this.crossbarVideoInput1 = this.GetCurrentCrossbarInput(iamcrossbar); } } if (this.needToSimulateTrigger1) { this.needToSimulateTrigger1 = false; if (flag && this.provideSnapshots1) { iamvideoControl.SetMode(pin, VideoControlFlags.Trigger); } } if (this.needToDisplayPropertyPage1) { this.needToDisplayPropertyPage1 = false; this.DisplayPropertyPage(this.parentWindowForPropertyPage1, this.sourceObject1); if (iamcrossbar != null) { this.crossbarVideoInput1 = this.GetCurrentCrossbarInput(iamcrossbar); } } if (this.needToDisplayCrossBarPropertyPage1) { this.needToDisplayCrossBarPropertyPage1 = false; if (iamcrossbar != null) { this.DisplayPropertyPage(this.parentWindowForPropertyPage1, iamcrossbar); this.crossbarVideoInput1 = this.GetCurrentCrossbarInput(iamcrossbar); } } if (this.stopEvent1.WaitOne(100, false)) { goto IL_54E; } } reason = ReasonToFinishPlaying.DeviceLost; IL_54E: mediaControl.Stop1(); } } catch (Exception ex) { if (this.VideoSourceError != null) { this.VideoSourceError(this, new VideoSourceErrorEventArgs(ex.Message)); } } finally { captureGraphBuilder = null; filterGraph = null; baseFilter = null; iamvideoControl = null; pin = null; iamcrossbar = null; baseFilter2 = null; baseFilter3 = null; sampleGrabber = null; sampleGrabber2 = null; if (obj2 != null) { Marshal.ReleaseComObject(obj2); obj2 = null; } if (this.sourceObject1 != null) { Marshal.ReleaseComObject(this.sourceObject1); this.sourceObject1 = null; } if (obj3 != null) { Marshal.ReleaseComObject(obj3); obj3 = null; } if (obj4 != null) { Marshal.ReleaseComObject(obj4); obj4 = null; } if (obj != null) { Marshal.ReleaseComObject(obj); obj = null; } if (obj5 != null) { Marshal.ReleaseComObject(obj5); obj5 = null; } } if (this.PlayingFinished != null) { this.PlayingFinished(this, reason); } }
/// <summary> /// Shut down capture. /// This is used to release all resources needed by the capture graph. /// </summary> public void Dispose() { try { // To stop the capture filter before stopping the media control // seems to solve the problem described in the next comment. // sancta simplicitas... if (this.capFilter != null) { this.capFilter.Stop(); } // The stop or stopwhenready methods sometimes hang ... // This is a multithreading issue but I don´t solved it yet // But stopping is needed, otherwise the video device // is not disposed fast enough (due to GC) so at next initialization // with other params the video device seems to be in // use and the GraphBuilder render mehtod fails. if (this.mediaControl != null) { int hr = this.mediaControl.Stop(); } this.isRunning = false; } catch (Exception ex) { ErrorLogger.ProcessException(ex, false); } if (this.capFilter != null) { Marshal.ReleaseComObject(this.capFilter); this.capFilter = null; this.cameraControl = null; this.videoControl = null; this.videoStreamConfig = null; } if (this.videoProcAmp != null) { Marshal.ReleaseComObject(this.videoProcAmp); this.videoProcAmp = null; } if (this.sampGrabber != null) { Marshal.ReleaseComObject(this.sampGrabber); this.sampGrabber = null; } if (this.graphBuilder != null) { Marshal.ReleaseComObject(this.graphBuilder); this.graphBuilder = null; this.mediaControl = null; this.hasValidGraph = false; } if (this.capGraph != null) { Marshal.ReleaseComObject(this.capGraph); this.capGraph = null; } if (this.map != IntPtr.Zero) { UnmapViewOfFile(this.map); this.map = IntPtr.Zero; } if (this.section != IntPtr.Zero) { CloseHandle(this.section); this.section = IntPtr.Zero; } #if DEBUG if (this.rotEntry != null) { this.rotEntry.Dispose(); } #endif }
private void SetConfigParms(ICaptureGraphBuilder2 capBuilder, IBaseFilter capFilter, VideoFormatHelper.SupportedVideoFormat selectedFormat, ref float iFrameRate, ref int iWidth, ref int iHeight) { object o; IAMStreamConfig videoStreamConfig; IAMVideoControl videoControl = capFilter as IAMVideoControl; int hr = capBuilder.FindInterface(PinCategory.Capture, MediaType.Video, capFilter, typeof(IAMStreamConfig).GUID, out o); videoStreamConfig = o as IAMStreamConfig; try { if (videoStreamConfig == null) { throw new Exception("Failed to get IAMStreamConfig"); } int iCount = 0, iSize = 0; hr = videoStreamConfig.GetNumberOfCapabilities(out iCount, out iSize); DsError.ThrowExceptionForHR(hr); VideoInfoHeader vMatching = null; VideoFormatHelper.SupportedVideoFormat entry = null; IntPtr taskMemPointer = Marshal.AllocCoTaskMem(iSize); AMMediaType pmtConfig = null; for (int iFormat = 0; iFormat < iCount; iFormat++) { IntPtr ptr = IntPtr.Zero; hr = videoStreamConfig.GetStreamCaps(iFormat, out pmtConfig, taskMemPointer); DsError.ThrowExceptionForHR(hr); vMatching = (VideoInfoHeader)Marshal.PtrToStructure(pmtConfig.formatPtr, typeof(VideoInfoHeader)); if (vMatching.BmiHeader.BitCount > 0) { entry = new VideoFormatHelper.SupportedVideoFormat() { Width = vMatching.BmiHeader.Width, Height = vMatching.BmiHeader.Height, BitCount = vMatching.BmiHeader.BitCount, FrameRate = 10000000.0 / vMatching.AvgTimePerFrame }; if (entry.Matches(selectedFormat)) { // WE FOUND IT !!! break; } } vMatching = null; } if (vMatching != null) { hr = videoStreamConfig.SetFormat(pmtConfig); DsError.ThrowExceptionForHR(hr); iFrameRate = 10000000 / vMatching.AvgTimePerFrame; iWidth = vMatching.BmiHeader.Width; iHeight = vMatching.BmiHeader.Height; } else { AMMediaType media; hr = videoStreamConfig.GetFormat(out media); DsError.ThrowExceptionForHR(hr); // Copy out the videoinfoheader VideoInfoHeader v = new VideoInfoHeader(); Marshal.PtrToStructure(media.formatPtr, v); // If overriding the framerate, set the frame rate if (iFrameRate > 0) { v.AvgTimePerFrame = (int)Math.Round(10000000 / iFrameRate); } else { iFrameRate = 10000000 / v.AvgTimePerFrame; } // If overriding the width, set the width if (iWidth > 0) { v.BmiHeader.Width = iWidth; } else { iWidth = v.BmiHeader.Width; } // If overriding the Height, set the Height if (iHeight > 0) { v.BmiHeader.Height = iHeight; } else { iHeight = v.BmiHeader.Height; } // Copy the media structure back Marshal.StructureToPtr(v, media.formatPtr, false); // Set the new format hr = videoStreamConfig.SetFormat(media); DsError.ThrowExceptionForHR(hr); DsUtils.FreeAMMediaType(media); media = null; } Marshal.FreeCoTaskMem(taskMemPointer); DsUtils.FreeAMMediaType(pmtConfig); pmtConfig = null; } finally { Marshal.ReleaseComObject(videoStreamConfig); } }
public override void Cleanup() { try { // To stop the capture filter before stopping the media control // seems to solve the problem described in the next comment. // sancta simplicitas... if (capFilter != null) { capFilter.Stop(); } // The stop or stopwhenready methods sometimes hang ... // This is a multithreading issue but I don´t solved it yet // But stopping is needed, otherwise the video device // is not disposed fast enough (due to GC) so at next initialization // with other params the video device seems to be in // use and the GraphBuilder render mehtod fails. if (mediaControl != null) { // This hangs when closing the GT int hr = mediaControl.Stop(); } isRunning = false; } catch (Exception) { //ErrorLogger.ProcessException(ex, false); } if (capFilter != null) { Marshal.ReleaseComObject(capFilter); capFilter = null; cameraControl = null; videoControl = null; videoStreamConfig = null; } if (videoProcAmp != null) { Marshal.ReleaseComObject(videoProcAmp); videoProcAmp = null; } if (sampGrabber != null) { Marshal.ReleaseComObject(sampGrabber); sampGrabber = null; } if (graphBuilder != null) { Marshal.ReleaseComObject(graphBuilder); graphBuilder = null; mediaControl = null; hasValidGraph = false; } if (capGraph != null) { Marshal.ReleaseComObject(capGraph); capGraph = null; } if (map != IntPtr.Zero) { UnmapViewOfFile(map); map = IntPtr.Zero; } if (section != IntPtr.Zero) { CloseHandle(section); section = IntPtr.Zero; } #if DEBUG if (this.rotEntry != null) { // This hangs when closing the GT this.rotEntry.Dispose(); } #endif }
public void PrepareCapture(int i_width, int i_height, float i_frame_rate) { const int BBP = 32; //既にキャプチャ中なら諦める。 if (this.m_graphi_active) { throw new Exception(); } //現在確保中のグラフインスタンスを全て削除 CleanupGraphiObjects(); int hr; ISampleGrabber sampGrabber = null; IBaseFilter capFilter = null; IPin pSampleIn = null; //グラフビルダを作る。 this.m_FilterGraph = new FilterGraph() as IFilterGraph2; try { //フィルタグラフにキャプチャを追加して、capFilterにピンを受け取る。 hr = m_FilterGraph.AddSourceFilterForMoniker(this.m_dev.Mon, null, this.m_dev.Name, out capFilter); DsError.ThrowExceptionForHR(hr); //stillピンを探す m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Still, 0); //stillピンが無ければPreviewを探す。 if (m_pinStill == null) { m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Preview, 0); } // Still haven't found one. Need to put a splitter in so we have // one stream to capture the bitmap from, and one to display. Ok, we // don't *have* to do it that way, but we are going to anyway. if (m_pinStill == null) { // There is no still pin m_VidControl = null; m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); } else { // Get a control pointer (used in Click()) m_VidControl = capFilter as IAMVideoControl; m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); } if (i_height + i_width + BBP > 0) { SetConfigParms(m_pinStill, i_width, i_height, i_frame_rate, BBP); } // Get the SampleGrabber interface sampGrabber = new SampleGrabber() as ISampleGrabber; //sampGrabberの設定 IBaseFilter baseGrabFlt = sampGrabber as IBaseFilter; ConfigureSampleGrabber(sampGrabber); pSampleIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0); // Add the sample grabber to the graph hr = m_FilterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber"); DsError.ThrowExceptionForHR(hr); if (m_VidControl == null) { // Connect the Still pin to the sample grabber hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); DsError.ThrowExceptionForHR(hr); } else { // Connect the Still pin to the sample grabber hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); DsError.ThrowExceptionForHR(hr); } hr = sampGrabber.GetConnectedMediaType(this._capture_mediatype); DsError.ThrowExceptionForHR(hr); //ビデオフォーマット等の更新 upateVideoInfo(sampGrabber); } finally { if (sampGrabber != null) { Marshal.ReleaseComObject(sampGrabber); sampGrabber = null; } if (pSampleIn != null) { Marshal.ReleaseComObject(pSampleIn); pSampleIn = null; } } }
// Set the Framerate, and video size private void SetConfigParms(ICaptureGraphBuilder2 capGraph, IBaseFilter capFilter, int iFrameRate, int iWidth, int iHeight) { int hr; object o; AMMediaType media; IAMStreamConfig videoStreamConfig; IAMVideoControl videoControl = capFilter as IAMVideoControl; // Find the stream config interface hr = capGraph.FindInterface( PinCategory.Capture, MediaType.Video, capFilter, typeof(IAMStreamConfig).GUID, out o); videoStreamConfig = o as IAMStreamConfig; try { if (videoStreamConfig == null) { throw new Exception("Failed to get IAMStreamConfig"); } hr = videoStreamConfig.GetFormat(out media); DsError.ThrowExceptionForHR(hr); // copy out the videoinfoheader VideoInfoHeader v = new VideoInfoHeader(); Marshal.PtrToStructure(media.formatPtr, v); // if overriding the framerate, set the frame rate if (iFrameRate > 0) { v.AvgTimePerFrame = 10000000 / iFrameRate; } // if overriding the width, set the width if (iWidth > 0) { v.BmiHeader.Width = iWidth; } // if overriding the Height, set the Height if (iHeight > 0) { v.BmiHeader.Height = iHeight; } // Copy the media structure back Marshal.StructureToPtr(v, media.formatPtr, false); // Set the new format hr = videoStreamConfig.SetFormat(media); DsError.ThrowExceptionForHR(hr); DsUtils.FreeAMMediaType(media); media = null; // Fix upsidedown video if (videoControl != null) { VideoControlFlags pCapsFlags; IPin pPin = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); hr = videoControl.GetCaps(pPin, out pCapsFlags); DsError.ThrowExceptionForHR(hr); if ((pCapsFlags & VideoControlFlags.FlipVertical) > 0) { hr = videoControl.GetMode(pPin, out pCapsFlags); DsError.ThrowExceptionForHR(hr); hr = videoControl.SetMode(pPin, 0); } } } finally { Marshal.ReleaseComObject(videoStreamConfig); } }
public void PrepareCapture(int i_width, int i_height,float i_frame_rate) { const int BBP = 32; //既にキャプチャ中なら諦める。 if (this.m_graphi_active) { throw new Exception(); } //現在確保中のグラフインスタンスを全て削除 CleanupGraphiObjects(); int hr; ISampleGrabber sampGrabber = null; IBaseFilter capFilter = null; IPin pSampleIn = null; //グラフビルダを作る。 this.m_FilterGraph = new FilterGraph() as IFilterGraph2; try { //フィルタグラフにキャプチャを追加して、capFilterにピンを受け取る。 hr = m_FilterGraph.AddSourceFilterForMoniker(this.m_dev.Mon, null, this.m_dev.Name, out capFilter); DsError.ThrowExceptionForHR(hr); //stillピンを探す m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Still, 0); //stillピンが無ければPreviewを探す。 if (m_pinStill == null) { m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Preview, 0); } // Still haven't found one. Need to put a splitter in so we have // one stream to capture the bitmap from, and one to display. Ok, we // don't *have* to do it that way, but we are going to anyway. if (m_pinStill == null) { // There is no still pin m_VidControl = null; m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); }else{ // Get a control pointer (used in Click()) m_VidControl = capFilter as IAMVideoControl; m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); } if (i_height + i_width + BBP > 0) { SetConfigParms(m_pinStill, i_width, i_height,i_frame_rate, BBP); } // Get the SampleGrabber interface sampGrabber = new SampleGrabber() as ISampleGrabber; //sampGrabberの設定 IBaseFilter baseGrabFlt = sampGrabber as IBaseFilter; ConfigureSampleGrabber(sampGrabber); pSampleIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0); // Add the sample grabber to the graph hr = m_FilterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber"); DsError.ThrowExceptionForHR(hr); if (m_VidControl == null) { // Connect the Still pin to the sample grabber hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); DsError.ThrowExceptionForHR(hr); }else{ // Connect the Still pin to the sample grabber hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); DsError.ThrowExceptionForHR(hr); } hr = sampGrabber.GetConnectedMediaType(this._capture_mediatype); DsError.ThrowExceptionForHR(hr); //ビデオフォーマット等の更新 upateVideoInfo(sampGrabber); } finally { if (sampGrabber != null) { Marshal.ReleaseComObject(sampGrabber); sampGrabber = null; } if (pSampleIn != null) { Marshal.ReleaseComObject(pSampleIn); pSampleIn = null; } } }
/// <summary> /// Set the Framerate, and video size /// </summary> /// <param name="capGraph">The <see cref="ICaptureGraphBuilder2"/> interface.</param> /// <param name="capFilter">The <see cref="IBaseFilter"/> of the capture device.</param> /// <param name="frameRate">The new framerate to be used.</param> /// <param name="width">The new video width to be used.</param> /// <param name="height">The new video height to be used.</param> private void SetConfigParms(ICaptureGraphBuilder2 capGraph, IBaseFilter capFilter, int frameRate, int width, int height) { int hr; object o; AMMediaType media = null; // Find the stream config interface hr = this.capGraph.FindInterface(PinCategory.Capture, MediaType.Video, capFilter, typeof(IAMStreamConfig).GUID, out o); videoControl = capFilter as IAMVideoControl; videoStreamConfig = o as IAMStreamConfig; //if (videoStreamConfig == null) // ErrorLogger.WriteLine("Error in Capture.SetConfigParams(). Failed to get IAMStreamConfig"); // Get the existing format block if (videoStreamConfig != null) hr = videoStreamConfig.GetFormat(out media); //if (hr != 0) // ErrorLogger.WriteLine("Could not SetConfigParms in Camera.Capture. Message: " + DsError.GetErrorText(hr)); // copy out the videoinfoheader var v = new VideoInfoHeader(); Marshal.PtrToStructure(media.formatPtr, v); // if overriding set values if (frameRate > 0) { v.AvgTimePerFrame = 10000000 / frameRate; this.fps = frameRate; } else { this.fps = (int)(10000000 / v.AvgTimePerFrame); } if (width > 0) v.BmiHeader.Width = width; if (height > 0) v.BmiHeader.Height = height; // Copy the media structure back Marshal.StructureToPtr(v, media.formatPtr, true); // Set the new format if (videoStreamConfig != null) hr = videoStreamConfig.SetFormat(media); //if (hr != 0) // ErrorLogger.WriteLine( // "Error while setting new camera format (videoStreamConfig) in Camera.Capture. Message: " + // DsError.GetErrorText(hr)); DsUtils.FreeAMMediaType(media); media = null; }
/// <summary> build the capture graph for grabber. </summary> private void SetupGraph(DsDevice dev, int iWidth, int iHeight, short iBPP, Control hControl) { int hr; ISampleGrabber sampGrabber = null; IBaseFilter capFilter = null; IPin pCaptureOut = null; IPin pSampleIn = null; IPin pRenderIn = null; // Get the graphbuilder object m_FilterGraph = new FilterGraph() as IFilterGraph2; try { #if DEBUG m_rot = new DsROTEntry(m_FilterGraph); #endif // add the video input device hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter); DsError.ThrowExceptionForHR(hr); // Find the still pin m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Still, 0); // Didn't find one. Is there a preview pin? if (m_pinStill == null) { m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Preview, 0); } // Still haven't found one. Need to put a splitter in so we have // one stream to capture the bitmap from, and one to display. Ok, we // don't *have* to do it that way, but we are going to anyway. if (m_pinStill == null) { IPin pRaw = null; IPin pSmart = null; // There is no still pin m_VidControl = null; // Add a splitter IBaseFilter iSmartTee = (IBaseFilter)new SmartTee(); try { hr = m_FilterGraph.AddFilter(iSmartTee, "SmartTee"); DsError.ThrowExceptionForHR(hr); // Find the find the capture pin from the video device and the // input pin for the splitter, and connnect them pRaw = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); pSmart = DsFindPin.ByDirection(iSmartTee, PinDirection.Input, 0); hr = m_FilterGraph.Connect(pRaw, pSmart); DsError.ThrowExceptionForHR(hr); // Now set the capture and still pins (from the splitter) m_pinStill = DsFindPin.ByName(iSmartTee, "Preview"); pCaptureOut = DsFindPin.ByName(iSmartTee, "Capture"); // If any of the default config items are set, perform the config // on the actual video device (rather than the splitter) if (iHeight + iWidth + iBPP > 0) { SetConfigParms(pRaw, iWidth, iHeight, iBPP); } } finally { if (pRaw != null) { Marshal.ReleaseComObject(pRaw); } if (pRaw != pSmart) { Marshal.ReleaseComObject(pSmart); } if (pRaw != iSmartTee) { Marshal.ReleaseComObject(iSmartTee); } } } else { // Get a control pointer (used in Click()) m_VidControl = capFilter as IAMVideoControl; pCaptureOut = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); // If any of the default config items are set if (iHeight + iWidth + iBPP > 0) { SetConfigParms(m_pinStill, iWidth, iHeight, iBPP); } } // Get the SampleGrabber interface sampGrabber = new SampleGrabber() as ISampleGrabber; // Configure the sample grabber IBaseFilter baseGrabFlt = sampGrabber as IBaseFilter; ConfigureSampleGrabber(sampGrabber); pSampleIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0); // Get the default video renderer IBaseFilter pRenderer = new VideoRendererDefault() as IBaseFilter; hr = m_FilterGraph.AddFilter(pRenderer, "Renderer"); DsError.ThrowExceptionForHR(hr); pRenderIn = DsFindPin.ByDirection(pRenderer, PinDirection.Input, 0); // Add the sample grabber to the graph hr = m_FilterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber"); DsError.ThrowExceptionForHR(hr); if (m_VidControl == null) { // Connect the Still pin to the sample grabber hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); DsError.ThrowExceptionForHR(hr); // Connect the capture pin to the renderer hr = m_FilterGraph.Connect(pCaptureOut, pRenderIn); DsError.ThrowExceptionForHR(hr); } else { // Connect the capture pin to the renderer hr = m_FilterGraph.Connect(pCaptureOut, pRenderIn); DsError.ThrowExceptionForHR(hr); // Connect the Still pin to the sample grabber hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); DsError.ThrowExceptionForHR(hr); } // Learn the video properties SaveSizeInfo(sampGrabber); ConfigVideoWindow(hControl); // Start the graph IMediaControl mediaCtrl = m_FilterGraph as IMediaControl; hr = mediaCtrl.Run(); DsError.ThrowExceptionForHR(hr); } finally { if (sampGrabber != null) { Marshal.ReleaseComObject(sampGrabber); sampGrabber = null; } if (pCaptureOut != null) { Marshal.ReleaseComObject(pCaptureOut); pCaptureOut = null; } if (pRenderIn != null) { Marshal.ReleaseComObject(pRenderIn); pRenderIn = null; } if (pSampleIn != null) { Marshal.ReleaseComObject(pSampleIn); pSampleIn = null; } } }
private void WorkerThread(bool runGraph) { ReasonToFinishPlaying reason = ReasonToFinishPlaying.StoppedByUser; bool flag = false; Grabber grabber = new Grabber(this, snapshotMode: false); Grabber grabber2 = new Grabber(this, snapshotMode: true); object obj = null; object obj2 = null; object obj3 = null; object obj4 = null; object retInterface = null; ICaptureGraphBuilder2 captureGraphBuilder = null; IFilterGraph2 filterGraph = null; IBaseFilter baseFilter = null; IBaseFilter baseFilter2 = null; IBaseFilter baseFilter3 = null; ISampleGrabber sampleGrabber = null; ISampleGrabber sampleGrabber2 = null; IMediaControl mediaControl = null; IAMVideoControl iAMVideoControl = null; IMediaEventEx mediaEventEx = null; IPin pin = null; IAMCrossbar iAMCrossbar = null; try { Type typeFromCLSID = Type.GetTypeFromCLSID(Clsid.CaptureGraphBuilder2); if (typeFromCLSID == null) { throw new ApplicationException("Failed creating capture graph builder"); } obj = Activator.CreateInstance(typeFromCLSID); captureGraphBuilder = (ICaptureGraphBuilder2)obj; typeFromCLSID = Type.GetTypeFromCLSID(Clsid.FilterGraph); if (typeFromCLSID == null) { throw new ApplicationException("Failed creating filter graph"); } obj2 = Activator.CreateInstance(typeFromCLSID); filterGraph = (IFilterGraph2)obj2; captureGraphBuilder.SetFiltergraph((IGraphBuilder)filterGraph); sourceObject = FilterInfo.CreateFilter(deviceMoniker); if (sourceObject == null) { throw new ApplicationException("Failed creating device object for moniker"); } baseFilter = (IBaseFilter)sourceObject; try { iAMVideoControl = (IAMVideoControl)sourceObject; } catch { } typeFromCLSID = Type.GetTypeFromCLSID(Clsid.SampleGrabber); if (typeFromCLSID == null) { throw new ApplicationException("Failed creating sample grabber"); } obj3 = Activator.CreateInstance(typeFromCLSID); sampleGrabber = (ISampleGrabber)obj3; baseFilter2 = (IBaseFilter)obj3; obj4 = Activator.CreateInstance(typeFromCLSID); sampleGrabber2 = (ISampleGrabber)obj4; baseFilter3 = (IBaseFilter)obj4; filterGraph.AddFilter(baseFilter, "source"); filterGraph.AddFilter(baseFilter2, "grabber_video"); filterGraph.AddFilter(baseFilter3, "grabber_snapshot"); AMMediaType aMMediaType = new AMMediaType(); aMMediaType.MajorType = MediaType.Video; aMMediaType.SubType = MediaSubType.RGB24; sampleGrabber.SetMediaType(aMMediaType); sampleGrabber2.SetMediaType(aMMediaType); captureGraphBuilder.FindInterface(FindDirection.UpstreamOnly, Guid.Empty, baseFilter, typeof(IAMCrossbar).GUID, out retInterface); if (retInterface != null) { iAMCrossbar = (IAMCrossbar)retInterface; } isCrossbarAvailable = (iAMCrossbar != null); crossbarVideoInputs = ColletCrossbarVideoInputs(iAMCrossbar); if (iAMVideoControl != null) { captureGraphBuilder.FindPin(sourceObject, PinDirection.Output, PinCategory.StillImage, MediaType.Video, unconnected: false, 0, out pin); if (pin != null) { iAMVideoControl.GetCaps(pin, out VideoControlFlags flags); flag = ((flags & VideoControlFlags.ExternalTriggerEnable) != 0); } } sampleGrabber.SetBufferSamples(bufferThem: false); sampleGrabber.SetOneShot(oneShot: false); sampleGrabber.SetCallback(grabber, 1); sampleGrabber2.SetBufferSamples(bufferThem: true); sampleGrabber2.SetOneShot(oneShot: false); sampleGrabber2.SetCallback(grabber2, 1); GetPinCapabilitiesAndConfigureSizeAndRate(captureGraphBuilder, baseFilter, PinCategory.Capture, videoResolution, ref videoCapabilities); if (flag) { GetPinCapabilitiesAndConfigureSizeAndRate(captureGraphBuilder, baseFilter, PinCategory.StillImage, snapshotResolution, ref snapshotCapabilities); } else { snapshotCapabilities = new VideoCapabilities[0]; } 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) { captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Video, baseFilter, null, baseFilter2); if (sampleGrabber.GetConnectedMediaType(aMMediaType) == 0) { VideoInfoHeader videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(aMMediaType.FormatPtr, typeof(VideoInfoHeader)); grabber.Width = videoInfoHeader.BmiHeader.Width; grabber.Height = videoInfoHeader.BmiHeader.Height; aMMediaType.Dispose(); } if (flag && provideSnapshots) { captureGraphBuilder.RenderStream(PinCategory.StillImage, MediaType.Video, baseFilter, null, baseFilter3); if (sampleGrabber2.GetConnectedMediaType(aMMediaType) == 0) { VideoInfoHeader videoInfoHeader2 = (VideoInfoHeader)Marshal.PtrToStructure(aMMediaType.FormatPtr, typeof(VideoInfoHeader)); grabber2.Width = videoInfoHeader2.BmiHeader.Width; grabber2.Height = videoInfoHeader2.BmiHeader.Height; aMMediaType.Dispose(); } } mediaControl = (IMediaControl)obj2; mediaEventEx = (IMediaEventEx)obj2; mediaControl.Run(); if (flag && provideSnapshots) { startTime = DateTime.Now; iAMVideoControl.SetMode(pin, VideoControlFlags.ExternalTriggerEnable); } do { if (mediaEventEx != null && mediaEventEx.GetEvent(out DsEvCode lEventCode, out IntPtr lParam, out IntPtr lParam2, 0) >= 0) { mediaEventEx.FreeEventParams(lEventCode, lParam, lParam2); if (lEventCode == DsEvCode.DeviceLost) { reason = ReasonToFinishPlaying.DeviceLost; break; } } if (needToSetVideoInput) { needToSetVideoInput = false; if (isCrossbarAvailable.Value) { SetCurrentCrossbarInput(iAMCrossbar, crossbarVideoInput); crossbarVideoInput = GetCurrentCrossbarInput(iAMCrossbar); } } if (needToSimulateTrigger) { needToSimulateTrigger = false; if (flag && provideSnapshots) { iAMVideoControl.SetMode(pin, VideoControlFlags.Trigger); } } if (needToDisplayPropertyPage) { needToDisplayPropertyPage = false; DisplayPropertyPage(parentWindowForPropertyPage, sourceObject); if (iAMCrossbar != null) { crossbarVideoInput = GetCurrentCrossbarInput(iAMCrossbar); } } if (needToDisplayCrossBarPropertyPage) { needToDisplayCrossBarPropertyPage = false; if (iAMCrossbar != null) { DisplayPropertyPage(parentWindowForPropertyPage, iAMCrossbar); crossbarVideoInput = GetCurrentCrossbarInput(iAMCrossbar); } } }while (!stopEvent.WaitOne(100, exitContext: false)); mediaControl.Stop(); } } catch (Exception ex) { if (this.VideoSourceError != null) { this.VideoSourceError(this, new VideoSourceErrorEventArgs(ex.Message)); } } finally { captureGraphBuilder = null; filterGraph = null; baseFilter = null; mediaControl = null; iAMVideoControl = null; mediaEventEx = null; pin = null; iAMCrossbar = null; baseFilter2 = null; baseFilter3 = null; sampleGrabber = null; sampleGrabber2 = null; if (obj2 != null) { Marshal.ReleaseComObject(obj2); obj2 = null; } if (sourceObject != null) { Marshal.ReleaseComObject(sourceObject); sourceObject = null; } if (obj3 != null) { Marshal.ReleaseComObject(obj3); obj3 = null; } if (obj4 != null) { Marshal.ReleaseComObject(obj4); obj4 = null; } if (obj != null) { Marshal.ReleaseComObject(obj); obj = null; } if (retInterface != null) { Marshal.ReleaseComObject(retInterface); retInterface = null; } } if (this.PlayingFinished != null) { this.PlayingFinished(this, reason); } }
private void SetupGraph(DsDevice dev, int iWidth, int iHeight, short iBPP) { int hr; ISampleGrabber sampGrabber = null; IBaseFilter capFilter = null; IPin pCaptureOut = null; IPin pSampleIn = null; IPin pRenderIn = null; m_FilterGraph = new FilterGraph() as IFilterGraph2; try { #if DEBUG m_rot = new DsROTEntry(m_FilterGraph); #endif hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter); DsError.ThrowExceptionForHR(hr); m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Still, 0); if (m_pinStill == null) { m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Preview, 0); } if (m_pinStill == null) { IPin pRaw = null; IPin pSmart = null; m_VidControl = null; IBaseFilter iSmartTee = (IBaseFilter) new SmartTee(); try { hr = m_FilterGraph.AddFilter(iSmartTee, "SmartTee"); DsError.ThrowExceptionForHR(hr); pRaw = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); pSmart = DsFindPin.ByDirection(iSmartTee, PinDirection.Input, 0); hr = m_FilterGraph.Connect(pRaw, pSmart); DsError.ThrowExceptionForHR(hr); m_pinStill = DsFindPin.ByName(iSmartTee, "Preview"); pCaptureOut = DsFindPin.ByName(iSmartTee, "Capture"); if (iHeight + iWidth + iBPP > 0) { SetConfigParms(pRaw, iWidth, iHeight, iBPP); } } finally { if (pRaw != null) { Marshal.ReleaseComObject(pRaw); } if (pRaw != pSmart) { Marshal.ReleaseComObject(pSmart); } if (pRaw != iSmartTee) { Marshal.ReleaseComObject(iSmartTee); } } } else { m_VidControl = capFilter as IAMVideoControl; pCaptureOut = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); if (iHeight + iWidth + iBPP > 0) { SetConfigParms(m_pinStill, iWidth, iHeight, iBPP); } } sampGrabber = new SampleGrabber() as ISampleGrabber; IBaseFilter baseGrabFlt = sampGrabber as IBaseFilter; ConfigureSampleGrabber(sampGrabber); pSampleIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0); IBaseFilter pRenderer = new VideoRendererDefault() as IBaseFilter; hr = m_FilterGraph.AddFilter(pRenderer, "Renderer"); DsError.ThrowExceptionForHR(hr); pRenderIn = DsFindPin.ByDirection(pRenderer, PinDirection.Input, 0); hr = m_FilterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber"); DsError.ThrowExceptionForHR(hr); if (m_VidControl == null) { hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); DsError.ThrowExceptionForHR(hr); hr = m_FilterGraph.Connect(pCaptureOut, pRenderIn); DsError.ThrowExceptionForHR(hr); } else { hr = m_FilterGraph.Connect(pCaptureOut, pRenderIn); DsError.ThrowExceptionForHR(hr); hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); DsError.ThrowExceptionForHR(hr); } SaveSizeInfo(sampGrabber); IMediaControl mediaCtrl = m_FilterGraph as IMediaControl; hr = mediaCtrl.Run(); DsError.ThrowExceptionForHR(hr); } finally { if (sampGrabber != null) { Marshal.ReleaseComObject(sampGrabber); sampGrabber = null; } if (pCaptureOut != null) { Marshal.ReleaseComObject(pCaptureOut); pCaptureOut = null; } if (pRenderIn != null) { Marshal.ReleaseComObject(pRenderIn); pRenderIn = null; } if (pSampleIn != null) { Marshal.ReleaseComObject(pSampleIn); pSampleIn = null; } } }
/// <summary> /// Start using the camera /// </summary> /// <returns>Indicate if the webcam was able to start</returns> public bool Start() { if (!started) { DsDevice[] devices = GetDevices(); if (devices.Length > 0) { DsDevice dev = devices[0]; // Initialize camera int hr; IBaseFilter capFilter = null; ISampleGrabber sampGrabber = null; IPin pCaptureOut = null; IPin pSampleIn = null; IPin pRenderIn = null; m_FilterGraph = new FilterGraph() as IFilterGraph2; try { hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter); if (m_pinStill == null) { m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Preview, 0); } // Still haven't found one. Need to put a splitter in so we have // one stream to capture the bitmap from, and one to display. Ok, we // don't *have* to do it that way, but we are going to anyway. if (m_pinStill == null) { IPin pRaw = null; IPin pSmart = null; // There is no still pin m_VidControl = null; // Add a splitter IBaseFilter iSmartTee = (IBaseFilter) new SmartTee(); try { hr = m_FilterGraph.AddFilter(iSmartTee, "SmartTee"); DsError.ThrowExceptionForHR(hr); // Find the find the capture pin from the video device and the // input pin for the splitter, and connnect them pRaw = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); pSmart = DsFindPin.ByDirection(iSmartTee, PinDirection.Input, 0); hr = m_FilterGraph.Connect(pRaw, pSmart); DsError.ThrowExceptionForHR(hr); // Now set the capture and still pins (from the splitter) m_pinStill = DsFindPin.ByName(iSmartTee, "Preview"); pCaptureOut = DsFindPin.ByName(iSmartTee, "Capture"); // If any of the default config items are set, perform the config // on the actual video device (rather than the splitter) if (captureHeight + captureWidth > 0) { SetConfigParms(pRaw, captureWidth, captureHeight, 24); } } finally { if (pRaw != null) { Marshal.ReleaseComObject(pRaw); } if (pRaw != pSmart) { Marshal.ReleaseComObject(pSmart); } if (pRaw != iSmartTee) { Marshal.ReleaseComObject(iSmartTee); } } } else { // Get a control pointer (used in Click()) m_VidControl = capFilter as IAMVideoControl; pCaptureOut = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); // If any of the default config items are set if (captureHeight + captureWidth > 0) { SetConfigParms(m_pinStill, captureWidth, captureHeight, 24); } } // Get the SampleGrabber interface sampGrabber = new SampleGrabber() as ISampleGrabber; // Configure the sample grabber IBaseFilter baseGrabFlt = sampGrabber as IBaseFilter; ConfigureSampleGrabber(sampGrabber); pSampleIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0); // Get the default video renderer IBaseFilter pRenderer = new VideoRendererDefault() as IBaseFilter; hr = m_FilterGraph.AddFilter(pRenderer, "Renderer"); DsError.ThrowExceptionForHR(hr); pRenderIn = DsFindPin.ByDirection(pRenderer, PinDirection.Input, 0); // Add the sample grabber to the graph hr = m_FilterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber"); DsError.ThrowExceptionForHR(hr); if (m_VidControl == null) { // Connect the Still pin to the sample grabber hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); DsError.ThrowExceptionForHR(hr); // Connect the capture pin to the renderer hr = m_FilterGraph.Connect(pCaptureOut, pRenderIn); DsError.ThrowExceptionForHR(hr); } else { // Connect the capture pin to the renderer hr = m_FilterGraph.Connect(pCaptureOut, pRenderIn); DsError.ThrowExceptionForHR(hr); // Connect the Still pin to the sample grabber hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); DsError.ThrowExceptionForHR(hr); } SaveSizeInfo(sampGrabber); ConfigVideoWindow(pictureBox); IMediaControl mediaCtrl = m_FilterGraph as IMediaControl; hr = mediaCtrl.Run(); DsError.ThrowExceptionForHR(hr); } finally { if (sampGrabber != null) { Marshal.ReleaseComObject(sampGrabber); sampGrabber = null; } if (pCaptureOut != null) { Marshal.ReleaseComObject(pCaptureOut); pCaptureOut = null; } if (pRenderIn != null) { Marshal.ReleaseComObject(pRenderIn); pRenderIn = null; } if (pSampleIn != null) { Marshal.ReleaseComObject(pSampleIn); pSampleIn = null; } } m_PictureReady = new ManualResetEvent(false); timer.Interval = (int)(1000 / framesPerSecond); timer.Start(); return(true); } } else { return(true); } return(false); }
/// <summary> build the capture graph for grabber. </summary> private void SetupGraph(DsDevice dev, int iWidth, int iHeight, short iBPP, Control hControl) { int hr; ISampleGrabber sampGrabber = null; IBaseFilter capFilter = null; IPin pCaptureOut = null; IPin pSampleIn = null; IPin pRenderIn = null; // Get the graphbuilder object m_FilterGraph = new FilterGraph() as IFilterGraph2; try { #if DEBUG m_rot = new DsROTEntry(m_FilterGraph); #endif // add the video input device hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out capFilter); DsError.ThrowExceptionForHR(hr); // Find the still pin m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Still, 0); // Didn't find one. Is there a preview pin? if (m_pinStill == null) { m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Preview, 0); } // Still haven't found one. Need to put a splitter in so we have // one stream to capture the bitmap from, and one to display. Ok, we // don't *have* to do it that way, but we are going to anyway. if (m_pinStill == null) { IPin pRaw = null; IPin pSmart = null; // There is no still pin m_VidControl = null; // Add a splitter IBaseFilter iSmartTee = (IBaseFilter) new SmartTee(); try { hr = m_FilterGraph.AddFilter(iSmartTee, "SmartTee"); DsError.ThrowExceptionForHR(hr); // Find the find the capture pin from the video device and the // input pin for the splitter, and connnect them pRaw = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); pSmart = DsFindPin.ByDirection(iSmartTee, PinDirection.Input, 0); hr = m_FilterGraph.Connect(pRaw, pSmart); DsError.ThrowExceptionForHR(hr); // Now set the capture and still pins (from the splitter) m_pinStill = DsFindPin.ByName(iSmartTee, "Preview"); pCaptureOut = DsFindPin.ByName(iSmartTee, "Capture"); // If any of the default config items are set, perform the config // on the actual video device (rather than the splitter) if (iHeight + iWidth + iBPP > 0) { SetConfigParms(pRaw, iWidth, iHeight, iBPP); } } finally { if (pRaw != null) { Marshal.ReleaseComObject(pRaw); } if (pRaw != pSmart) { Marshal.ReleaseComObject(pSmart); } if (pRaw != iSmartTee) { Marshal.ReleaseComObject(iSmartTee); } } } else { // Get a control pointer (used in Click()) m_VidControl = capFilter as IAMVideoControl; pCaptureOut = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0); // If any of the default config items are set if (iHeight + iWidth + iBPP > 0) { SetConfigParms(m_pinStill, iWidth, iHeight, iBPP); } } // Get the SampleGrabber interface sampGrabber = new SampleGrabber() as ISampleGrabber; // Configure the sample grabber IBaseFilter baseGrabFlt = sampGrabber as IBaseFilter; ConfigureSampleGrabber(sampGrabber); pSampleIn = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0); // Get the default video renderer IBaseFilter pRenderer = new VideoRendererDefault() as IBaseFilter; hr = m_FilterGraph.AddFilter(pRenderer, "Renderer"); DsError.ThrowExceptionForHR(hr); pRenderIn = DsFindPin.ByDirection(pRenderer, PinDirection.Input, 0); // Add the sample grabber to the graph hr = m_FilterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber"); DsError.ThrowExceptionForHR(hr); if (m_VidControl == null) { // Connect the Still pin to the sample grabber hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); DsError.ThrowExceptionForHR(hr); // Connect the capture pin to the renderer hr = m_FilterGraph.Connect(pCaptureOut, pRenderIn); DsError.ThrowExceptionForHR(hr); } else { // Connect the capture pin to the renderer hr = m_FilterGraph.Connect(pCaptureOut, pRenderIn); DsError.ThrowExceptionForHR(hr); // Connect the Still pin to the sample grabber hr = m_FilterGraph.Connect(m_pinStill, pSampleIn); DsError.ThrowExceptionForHR(hr); } // Learn the video properties SaveSizeInfo(sampGrabber); ConfigVideoWindow(hControl); // Start the graph IMediaControl mediaCtrl = m_FilterGraph as IMediaControl; hr = mediaCtrl.Run(); DsError.ThrowExceptionForHR(hr); } finally { if (sampGrabber != null) { Marshal.ReleaseComObject(sampGrabber); sampGrabber = null; } if (pCaptureOut != null) { Marshal.ReleaseComObject(pCaptureOut); pCaptureOut = null; } if (pRenderIn != null) { Marshal.ReleaseComObject(pRenderIn); pRenderIn = null; } if (pSampleIn != null) { Marshal.ReleaseComObject(pSampleIn); pSampleIn = null; } } }
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)); } }