/// build the capture graph for grabber. 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_graphBuilder = new FilterGraph() as IFilterGraph2; try { #if DEBUG m_rot = new DsROTEntry(m_graphBuilder); #endif // add the video input device hr = m_graphBuilder.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_graphBuilder.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_graphBuilder.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_graphBuilder.AddFilter(pRenderer, "Renderer"); DsError.ThrowExceptionForHR(hr); pRenderIn = DsFindPin.ByDirection(pRenderer, PinDirection.Input, 0); // Add the sample grabber to the graph hr = m_graphBuilder.AddFilter(baseGrabFlt, "Ds.NET Grabber"); DsError.ThrowExceptionForHR(hr); if (m_VidControl == null) { // Connect the Still pin to the sample grabber hr = m_graphBuilder.Connect(m_pinStill, pSampleIn); DsError.ThrowExceptionForHR(hr); // Connect the capture pin to the renderer hr = m_graphBuilder.Connect(pCaptureOut, pRenderIn); DsError.ThrowExceptionForHR(hr); } else { // Connect the capture pin to the renderer hr = m_graphBuilder.Connect(pCaptureOut, pRenderIn); DsError.ThrowExceptionForHR(hr); // Connect the Still pin to the sample grabber hr = m_graphBuilder.Connect(m_pinStill, pSampleIn); DsError.ThrowExceptionForHR(hr); } // Learn the video properties SaveSizeInfo(sampGrabber); ConfigVideoWindow(hControl); // Start the graph IMediaControl mediaCtrl = m_graphBuilder 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 BuildGraph(DirectShowLib.DsDevice dsDevice) { int hr = 0; pGraph = new FilterGraph() as IFilterGraph2; //graph builder ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); try { hr = pBuilder.SetFiltergraph(pGraph); DsError.ThrowExceptionForHR(hr); // Add camera IBaseFilter camera; //hr = pGraph.FindFilterByName(dsDevice.Name, out camera); hr = ((IFilterGraph2)pGraph).AddSourceFilterForMoniker(dsDevice.Mon, null, dsDevice.Name, out camera); DsError.ThrowExceptionForHR(hr); hr = pGraph.AddFilter(camera, "camera"); DsError.ThrowExceptionForHR(hr); // Set format for camera AMMediaType pmt = new AMMediaType(); pmt.majorType = MediaType.Video; pmt.subType = MediaSubType.MJPG; pmt.formatType = FormatType.VideoInfo; pmt.fixedSizeSamples = true; pmt.formatSize = 88; pmt.sampleSize = 2764800; pmt.temporalCompression = false; VideoInfoHeader format = new VideoInfoHeader(); format.SrcRect = new DsRect(); format.TargetRect = new DsRect(); format.BitRate = 663552000; format.AvgTimePerFrame = 333333; format.BmiHeader = new BitmapInfoHeader(); format.BmiHeader.Size = 40; format.BmiHeader.Width = 1280; format.BmiHeader.Height = 720; format.BmiHeader.Planes = 1; format.BmiHeader.BitCount = 24; format.BmiHeader.Compression = 1196444237; format.BmiHeader.ImageSize = 2764800; pmt.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(format)); Marshal.StructureToPtr(format, pmt.formatPtr, false); hr = ((IAMStreamConfig)DsFindPin.ByCategory(camera, PinCategory.Capture, 0)).SetFormat(pmt); //hr = ((IAMStreamConfig)GetPin(pUSB20Camera, "Capture")).SetFormat(pmt); DsUtils.FreeAMMediaType(pmt); DsError.ThrowExceptionForHR(hr); //add MJPG Decompressor IBaseFilter pMJPGDecompressor = (IBaseFilter)new MjpegDec(); hr = pGraph.AddFilter(pMJPGDecompressor, "MJPG Decompressor"); DsError.ThrowExceptionForHR(hr); //add color space converter IBaseFilter pColorSpaceConverter = (IBaseFilter)new Colour(); hr = pGraph.AddFilter(pColorSpaceConverter, "Color space converter"); DsError.ThrowExceptionForHR(hr); // Connect camera and MJPEG Decomp //hr = pGraph.ConnectDirect(GetPin(pUSB20Camera, "Capture"), GetPin(pMJPGDecompressor, "XForm In"), null); hr = pGraph.ConnectDirect(DsFindPin.ByCategory(camera, PinCategory.Capture, 0), DsFindPin.ByName(pMJPGDecompressor, "XForm In"), null); DsError.ThrowExceptionForHR(hr); // Connect MJPG Decomp and color space converter hr = pGraph.ConnectDirect(DsFindPin.ByName(pMJPGDecompressor, "XForm Out"), DsFindPin.ByName(pColorSpaceConverter, "Input"), null); DsError.ThrowExceptionForHR(hr); //add SampleGrabber //IBaseFilter pSampleGrabber = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_SampleGrabber)); //hr = pGraph.AddFilter(pSampleGrabber, "SampleGrabber"); IBaseFilter sampleGrabber = new SampleGrabber() as IBaseFilter; hr = pGraph.AddFilter(sampleGrabber, "Sample grabber"); DsError.ThrowExceptionForHR(hr); // Configure the samplegrabber AMMediaType pSampleGrabber_pmt = new AMMediaType(); pSampleGrabber_pmt.majorType = MediaType.Video; pSampleGrabber_pmt.subType = MediaSubType.ARGB32; pSampleGrabber_pmt.formatType = FormatType.VideoInfo; pSampleGrabber_pmt.fixedSizeSamples = true; pSampleGrabber_pmt.formatSize = 88; pSampleGrabber_pmt.sampleSize = 3686400; pSampleGrabber_pmt.temporalCompression = false; VideoInfoHeader pSampleGrabber_format = new VideoInfoHeader(); pSampleGrabber_format.SrcRect = new DsRect(); pSampleGrabber_format.TargetRect = new DsRect(); pSampleGrabber_format.BitRate = 884736885; pSampleGrabber_format.AvgTimePerFrame = 333333; pSampleGrabber_format.BmiHeader = new BitmapInfoHeader(); pSampleGrabber_format.BmiHeader.Size = 40; pSampleGrabber_format.BmiHeader.Width = 1280; pSampleGrabber_format.BmiHeader.Height = 720; pSampleGrabber_format.BmiHeader.Planes = 1; pSampleGrabber_format.BmiHeader.BitCount = 32; //pSampleGrabber_format.BmiHeader.Compression = 1196444237; pSampleGrabber_format.BmiHeader.ImageSize = 3686400; pSampleGrabber_pmt.formatPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(pSampleGrabber_format)); Marshal.StructureToPtr(pSampleGrabber_format, pSampleGrabber_pmt.formatPtr, false); hr = ((ISampleGrabber)sampleGrabber).SetMediaType(pSampleGrabber_pmt); DsError.ThrowExceptionForHR(hr); //connect MJPG dec and SampleGrabber //hr = pGraph.ConnectDirect(GetPin(pMJPGDecompressor, "XForm Out"), GetPin(pSampleGrabber, "Input"), null); hr = pGraph.ConnectDirect(DsFindPin.ByName(pColorSpaceConverter, "XForm Out"), DsFindPin.ByName(sampleGrabber, "Input"), null); DsError.ThrowExceptionForHR(hr); //set callback hr = ((ISampleGrabber)sampleGrabber).SetCallback(this, 1); DsError.ThrowExceptionForHR(hr); } finally { // Clean this mess up! } }