protected override void BuildGraph(string path) { // Build partial graph IPin videoOutput = null, audioOutput = null; { VideoRendererDefault videoRenderer = new VideoRendererDefault(); DSoundRender audioRenderer = new DSoundRender(); try { GraphBuilder.AddFilter(videoRenderer as IBaseFilter, "Default Video Renderer"); GraphBuilder.AddFilter(audioRenderer as IBaseFilter, "Default Audio Renderer"); GraphBuilder.RenderFile(path, null); // Get Connected Pins { IPin videoInput = Util.FindInputPin(videoRenderer as IBaseFilter); videoInput.ConnectedTo(out videoOutput); Util.FreePin(videoInput); IPin audioInput = Util.FindInputPin(audioRenderer as IBaseFilter); audioInput.ConnectedTo(out audioOutput); Util.FreePin(audioInput); } GraphBuilder.RemoveFilter(videoRenderer as IBaseFilter); GraphBuilder.RemoveFilter(audioRenderer as IBaseFilter); } finally { Marshal.ReleaseComObject(videoRenderer); Marshal.ReleaseComObject(audioRenderer); } } // build video grabber if (videoOutput != null) { this.VideoGrabber = BuildGrabber("Video", videoOutput, MEDIATYPE_Video, MEDIASUBTYPE_RGB32, FORMAT_VideoInfo, OnVideoFrame) as ISampleGrabber; this.VideoInfo = GetMediaFormat <VideoInfoHeader>(VideoGrabber); Marshal.ReleaseComObject(videoOutput); } // build audio grabber if (audioOutput != null) { this.AudioGrabber = BuildGrabber("Audio", audioOutput, MEDIATYPE_Audio, MEDIASUBTYPE_PCM, FORMAT_WaveFormatEx, OnAudioFrame) as ISampleGrabber; this.AudioInfo = GetMediaFormat <WaveFormatEx>(AudioGrabber); Marshal.ReleaseComObject(audioOutput); } }
/// <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; } } }
/// <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; } } }
protected override void BuildGraph(string path) { // Build partial graph IPin videoOutput = null, audioOutput = null; { VideoRendererDefault videoRenderer = new VideoRendererDefault(); DSoundRender audioRenderer = new DSoundRender(); try { GraphBuilder.AddFilter(videoRenderer as IBaseFilter, "Default Video Renderer"); GraphBuilder.AddFilter(audioRenderer as IBaseFilter, "Default Audio Renderer"); GraphBuilder.RenderFile(path, null); // Get Connected Pins { IPin videoInput = Util.FindInputPin(videoRenderer as IBaseFilter); videoInput.ConnectedTo(out videoOutput); Util.FreePin(videoInput); IPin audioInput = Util.FindInputPin(audioRenderer as IBaseFilter); audioInput.ConnectedTo(out audioOutput); Util.FreePin(audioInput); } GraphBuilder.RemoveFilter(videoRenderer as IBaseFilter); GraphBuilder.RemoveFilter(audioRenderer as IBaseFilter); } finally { Marshal.ReleaseComObject(videoRenderer); Marshal.ReleaseComObject(audioRenderer); } } // build video grabber if (videoOutput != null) { this.VideoGrabber = BuildGrabber("Video", videoOutput, MEDIATYPE_Video, MEDIASUBTYPE_RGB32, FORMAT_VideoInfo, OnVideoFrame) as ISampleGrabber; this.VideoInfo = GetMediaFormat<VideoInfoHeader>(VideoGrabber); Marshal.ReleaseComObject(videoOutput); } // build audio grabber if (audioOutput != null) { this.AudioGrabber = BuildGrabber("Audio", audioOutput, MEDIATYPE_Audio, MEDIASUBTYPE_PCM, FORMAT_WaveFormatEx, OnAudioFrame) as ISampleGrabber; this.AudioInfo = GetMediaFormat<WaveFormatEx>(AudioGrabber); Marshal.ReleaseComObject(audioOutput); } }
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> /// build the capture graph for grabber. /// </summary> /// <param name="strCapture">The STR capture.</param> /// <param name="strCompressor">The STR compressor.</param> /// <param name="strFileName">Name of the STR file.</param> /// <param name="iFrameRate">The i frame rate.</param> /// <param name="iWidth">Width of the i.</param> /// <param name="iHeight">Height of the i.</param> /// <param name="owner">The owner.</param> /// <param name="record">if set to <c>true</c> [record].</param> private void SetupGraph(string strCapture, string strCompressor, string strFileName, int iFrameRate, int iWidth, int iHeight, IntPtr owner, bool record) { ICaptureGraphBuilder2 captureGraphBuilder = null; ISampleGrabber sampGrabber = null; IBaseFilter theIPinTee = null; IBaseFilter mux = null; IFileSinkFilter sink = null; IBaseFilter captureDevice = null; IBaseFilter captureCompressor = null; IBaseFilter theRenderer = null; int hr = 0; try { //Create the filter for the selected video input captureDevice = CreateFilter(FilterCategory.VideoInputDevice, strCapture); //Create the filter for the selected video compressor captureCompressor = CreateFilter(FilterCategory.VideoCompressorCategory, strCompressor); //Create the Graph _graphBuilder = (IGraphBuilder)new FilterGraph(); //Create the Capture Graph Builder captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); // Attach the filter graph to the capture graph hr = captureGraphBuilder.SetFiltergraph(this._graphBuilder); checkHR(hr, "Error attaching filter graph to capture graph"); //Add the Video input device to the graph hr = _graphBuilder.AddFilter(captureDevice, "QUAVS input filter"); checkHR(hr, "Error attaching video input"); //setup cature device SetConfigParms(captureGraphBuilder, captureDevice, iFrameRate, iWidth, iHeight); //Add a sample grabber sampGrabber = (ISampleGrabber)new SampleGrabber(); ConfigureSampleGrabber(sampGrabber); hr = _graphBuilder.AddFilter((IBaseFilter)sampGrabber, "QUAVS SampleGrabber"); checkHR(hr, "Error adding sample grabber"); //connect capture device to SampleGrabber hr = _graphBuilder.Connect(GetPin(captureDevice, "Capture"), GetPin((IBaseFilter)sampGrabber, "Input")); checkHR(hr, "Error attaching sample grabber to capture pin"); //Add Ininite Pin Tee theIPinTee = (IBaseFilter)new InfTee(); hr = _graphBuilder.AddFilter(theIPinTee, "QUAVS Pin Tee"); checkHR(hr, "Error adding infinite tee pin"); //connect capture SampleGrabber to IPinTee hr = _graphBuilder.Connect(GetPin((IBaseFilter)sampGrabber, "Output"), GetPin(theIPinTee, "Input")); checkHR(hr, "Error adding SampleGrabber"); if (record) { //Add the Video compressor filter to the graph hr = _graphBuilder.AddFilter(captureCompressor, "QUAVS compressor filter"); checkHR(hr, "Error adding compressor filter"); //connect capture IPinTee output1 to compressor hr = _graphBuilder.Connect(GetPin(theIPinTee, "Output1"), GetPin(captureCompressor, "Input")); checkHR(hr, "Error adding TO DO"); //Create the file writer part of the graph. SetOutputFileName does this for us, and returns the mux and sink hr = captureGraphBuilder.SetOutputFileName(MediaSubType.Avi, strFileName, out mux, out sink); checkHR(hr, "Error adding mux filter or setting output file name"); //connect compressor to mux output hr = _graphBuilder.Connect(GetPin(captureCompressor, "Output"), GetPin(mux, "Input 01")); checkHR(hr, "Error connecting the compressor to mux"); // Get the default video renderer theRenderer = new VideoRendererDefault() as IBaseFilter; hr = _graphBuilder.AddFilter(theRenderer, "Renderer"); checkHR(hr, "Error adding screen renderer"); //connect capture TO DO hr = _graphBuilder.Connect(GetPin(theIPinTee, "Output2"), GetPin(theRenderer, "VMR Input0")); checkHR(hr, "Error connecting screen renderer"); } else { // Get the default video renderer theRenderer = new VideoRendererDefault() as IBaseFilter; hr = _graphBuilder.AddFilter(theRenderer, "Renderer"); checkHR(hr, "Error adding screen renderer"); //connect capture TO DO hr = _graphBuilder.Connect(GetPin(theIPinTee, "Output1"), GetPin(theRenderer, "VMR Input0")); checkHR(hr, "Error connecting screen renderer"); } SaveSizeInfo(sampGrabber); #if DEBUG _rot = new DsROTEntry(_graphBuilder); #endif if (owner != IntPtr.Zero) { //get the video window from the graph IVideoWindow videoWindow = null; videoWindow = (IVideoWindow)_graphBuilder; //Set the owener of the videoWindow to an IntPtr of some sort (the Handle of any control - could be a form / button etc.) hr = videoWindow.put_Owner(owner); DsError.ThrowExceptionForHR(hr); //Set the style of the video window hr = videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren); DsError.ThrowExceptionForHR(hr); hr = videoWindow.SetWindowPosition(0, 0, iWidth, iHeight); DsError.ThrowExceptionForHR(hr); // Make the video window visible hr = videoWindow.put_Visible(OABool.True); DsError.ThrowExceptionForHR(hr); } //Create the media control for controlling the graph _mediaCtrl = (IMediaControl)this._graphBuilder; } catch (Exception e) { TraceException.WriteLine(e); //Trace.WriteLine(e.Message); CloseInterfaces(); } finally { if (sink != null) { Marshal.ReleaseComObject(sink); sink = null; } if (mux != null) { Marshal.ReleaseComObject(mux); mux = null; } if (captureGraphBuilder != null) { Marshal.ReleaseComObject(captureGraphBuilder); captureGraphBuilder = null; } if (sampGrabber != null) { Marshal.ReleaseComObject(sampGrabber); sampGrabber = null; } if (theIPinTee != null) { Marshal.ReleaseComObject(theIPinTee); theIPinTee = null; } if (captureDevice != null) { Marshal.ReleaseComObject(captureDevice); captureDevice = null; } if (captureCompressor != null) { Marshal.ReleaseComObject(captureCompressor); captureCompressor = null; } if (theRenderer != null) { Marshal.ReleaseComObject(theRenderer); theRenderer = 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> /// <param name="strCapture">The STR capture.</param> /// <param name="strCompressor">The STR compressor.</param> /// <param name="strFileName">Name of the STR file.</param> /// <param name="iFrameRate">The i frame rate.</param> /// <param name="iWidth">Width of the i.</param> /// <param name="iHeight">Height of the i.</param> /// <param name="owner">The owner.</param> /// <param name="record">if set to <c>true</c> [record].</param> private void SetupGraph(string strCapture, string strCompressor, string strFileName, int iFrameRate, int iWidth, int iHeight, IntPtr owner, bool record) { ICaptureGraphBuilder2 captureGraphBuilder = null; ISampleGrabber sampGrabber = null; IBaseFilter theIPinTee = null; IBaseFilter mux = null; IFileSinkFilter sink = null; IBaseFilter captureDevice = null; IBaseFilter captureCompressor = null; IBaseFilter theRenderer = null; int hr = 0; try { //Create the filter for the selected video input captureDevice = CreateFilter(FilterCategory.VideoInputDevice, strCapture); //Create the filter for the selected video compressor captureCompressor = CreateFilter(FilterCategory.VideoCompressorCategory, strCompressor); //Create the Graph _graphBuilder = (IGraphBuilder) new FilterGraph(); //Create the Capture Graph Builder captureGraphBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); // Attach the filter graph to the capture graph hr = captureGraphBuilder.SetFiltergraph(this._graphBuilder); checkHR(hr, "Error attaching filter graph to capture graph"); //Add the Video input device to the graph hr = _graphBuilder.AddFilter(captureDevice, "QUAVS input filter"); checkHR(hr, "Error attaching video input"); //setup cature device SetConfigParms(captureGraphBuilder, captureDevice, iFrameRate, iWidth, iHeight); //Add a sample grabber sampGrabber = (ISampleGrabber) new SampleGrabber(); ConfigureSampleGrabber(sampGrabber); hr = _graphBuilder.AddFilter((IBaseFilter)sampGrabber, "QUAVS SampleGrabber"); checkHR(hr, "Error adding sample grabber"); //connect capture device to SampleGrabber hr = _graphBuilder.Connect(GetPin(captureDevice, "Capture"), GetPin((IBaseFilter)sampGrabber, "Input")); checkHR(hr, "Error attaching sample grabber to capture pin"); //Add Ininite Pin Tee theIPinTee = (IBaseFilter) new InfTee(); hr = _graphBuilder.AddFilter(theIPinTee, "QUAVS Pin Tee"); checkHR(hr, "Error adding infinite tee pin"); //connect capture SampleGrabber to IPinTee hr = _graphBuilder.Connect(GetPin((IBaseFilter)sampGrabber, "Output"), GetPin(theIPinTee, "Input")); checkHR(hr, "Error adding SampleGrabber"); if (record) { //Add the Video compressor filter to the graph hr = _graphBuilder.AddFilter(captureCompressor, "QUAVS compressor filter"); checkHR(hr, "Error adding compressor filter"); //connect capture IPinTee output1 to compressor hr = _graphBuilder.Connect(GetPin(theIPinTee, "Output1"), GetPin(captureCompressor, "Input")); checkHR(hr, "Error adding TO DO"); //Create the file writer part of the graph. SetOutputFileName does this for us, and returns the mux and sink hr = captureGraphBuilder.SetOutputFileName(MediaSubType.Avi, strFileName, out mux, out sink); checkHR(hr, "Error adding mux filter or setting output file name"); //connect compressor to mux output hr = _graphBuilder.Connect(GetPin(captureCompressor, "Output"), GetPin(mux, "Input 01")); checkHR(hr, "Error connecting the compressor to mux"); // Get the default video renderer theRenderer = new VideoRendererDefault() as IBaseFilter; hr = _graphBuilder.AddFilter(theRenderer, "Renderer"); checkHR(hr, "Error adding screen renderer"); //connect capture TO DO hr = _graphBuilder.Connect(GetPin(theIPinTee, "Output2"), GetPin(theRenderer, "VMR Input0")); checkHR(hr, "Error connecting screen renderer"); } else { // Get the default video renderer theRenderer = new VideoRendererDefault() as IBaseFilter; hr = _graphBuilder.AddFilter(theRenderer, "Renderer"); checkHR(hr, "Error adding screen renderer"); //connect capture TO DO hr = _graphBuilder.Connect(GetPin(theIPinTee, "Output1"), GetPin(theRenderer, "VMR Input0")); checkHR(hr, "Error connecting screen renderer"); } SaveSizeInfo(sampGrabber); #if DEBUG _rot = new DsROTEntry(_graphBuilder); #endif if (owner != IntPtr.Zero) { //get the video window from the graph IVideoWindow videoWindow = null; videoWindow = (IVideoWindow)_graphBuilder; //Set the owener of the videoWindow to an IntPtr of some sort (the Handle of any control - could be a form / button etc.) hr = videoWindow.put_Owner(owner); DsError.ThrowExceptionForHR(hr); //Set the style of the video window hr = videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren); DsError.ThrowExceptionForHR(hr); hr = videoWindow.SetWindowPosition(0, 0, iWidth, iHeight); DsError.ThrowExceptionForHR(hr); // Make the video window visible hr = videoWindow.put_Visible(OABool.True); DsError.ThrowExceptionForHR(hr); } //Create the media control for controlling the graph _mediaCtrl = (IMediaControl)this._graphBuilder; } catch (Exception e) { TraceException.WriteLine(e); //Trace.WriteLine(e.Message); CloseInterfaces(); } finally { if (sink != null) { Marshal.ReleaseComObject(sink); sink = null; } if (mux != null) { Marshal.ReleaseComObject(mux); mux = null; } if (captureGraphBuilder != null) { Marshal.ReleaseComObject(captureGraphBuilder); captureGraphBuilder = null; } if (sampGrabber != null) { Marshal.ReleaseComObject(sampGrabber); sampGrabber = null; } if (theIPinTee != null) { Marshal.ReleaseComObject(theIPinTee); theIPinTee = null; } if (captureDevice != null) { Marshal.ReleaseComObject(captureDevice); captureDevice = null; } if (captureCompressor != null) { Marshal.ReleaseComObject(captureCompressor); captureCompressor = null; } if (theRenderer != null) { Marshal.ReleaseComObject(theRenderer); theRenderer = null; } } }