public IVideoCapture CreateVideoCapture(string deviceName, IVideoResolutionSeletor selector) { return(new DirectShowVideoCapture(DeviceManager.GetVideoInputDevices().Single(d => d.Name.Equals(deviceName)), selector)); }
public DirectShowVideoCapture(DsDevice device, IVideoResolutionSeletor resolutionSelector) { if (device == null) { throw new ArgumentNullException("device", "Device must not be null"); } _dispatcher = Dispatcher.CurrentDispatcher; _deviceName = device.Name; ICaptureGraphBuilder2 graphBuilder = (ICaptureGraphBuilder2)(new CaptureGraphBuilder2()); IGraphBuilder graph = (IGraphBuilder)(new FilterGraphNoThread()); Marshal.ThrowExceptionForHR(graphBuilder.SetFiltergraph(graph)); IBaseFilter filter; IFilterGraph2 filterGraph = (IFilterGraph2)graph; DsError.ThrowExceptionForHR(filterGraph.AddSourceFilterForMoniker(device.Mon, null, device.Name, out filter)); object streamConfig; ICaptureGraphBuilder2 captureGraphBuilder = (ICaptureGraphBuilder2)graphBuilder; DsError.ThrowExceptionForHR(captureGraphBuilder.FindInterface(PinCategory.Capture, MediaType.Video, filter, typeof(IAMStreamConfig).GUID, out streamConfig)); var videoStreamConfig = streamConfig as IAMStreamConfig; int capCount, capSize; videoStreamConfig.GetNumberOfCapabilities(out capCount, out capSize); IntPtr taskMemPointer = Marshal.AllocCoTaskMem(capSize); AMMediaType pmtConfig = null; _allResolutions = new List <IVideoResolution>(capSize); for (int iFormat = 0; iFormat < capCount; iFormat++) { IntPtr ptr = IntPtr.Zero; videoStreamConfig.GetStreamCaps(iFormat, out pmtConfig, taskMemPointer); var v = (VideoInfoHeader)Marshal.PtrToStructure(pmtConfig.formatPtr, typeof(VideoInfoHeader)); var bmiHeader = v.BmiHeader; _allResolutions.Add(new VideoResolution(bmiHeader.Width, bmiHeader.Height, (int)bmiHeader.BitCount)); } _allResolutions.Sort(new VideoResolutionComparer()); _matchingResolutions = _allResolutions.Where(r => resolutionSelector == null || resolutionSelector.IsMatch(r.Width, r.Height, r.BitCount)).ToArray(); _resolution = _matchingResolutions.Last(); Marshal.FreeCoTaskMem(taskMemPointer); DsUtils.FreeAMMediaType(pmtConfig); AMMediaType media; DsError.ThrowExceptionForHR(videoStreamConfig.GetFormat(out media)); var videoInfo = new VideoInfoHeader(); Marshal.PtrToStructure(media.formatPtr, videoInfo); videoInfo.BmiHeader.Width = _resolution.Width; videoInfo.BmiHeader.Height = _resolution.Height; videoInfo.BmiHeader.BitCount = (short)_resolution.BitCount; Marshal.StructureToPtr(videoInfo, media.formatPtr, false); DsError.ThrowExceptionForHR(videoStreamConfig.SetFormat(media)); DsUtils.FreeAMMediaType(media); //sample grabber var mediaType = new AMMediaType { majorType = MediaType.Video, subType = MediaSubType.RGB24, }; _sampleGrabber = (ISampleGrabber)(new SampleGrabber()); Marshal.ThrowExceptionForHR(_sampleGrabber.SetMediaType(mediaType)); DsUtils.FreeAMMediaType(mediaType); Marshal.ThrowExceptionForHR(_sampleGrabber.SetOneShot(false)); Marshal.ThrowExceptionForHR(_sampleGrabber.SetBufferSamples(true)); Marshal.ThrowExceptionForHR(_sampleGrabber.SetCallback(this, 1)); IBaseFilter grabberFilter = (IBaseFilter)_sampleGrabber; Marshal.ThrowExceptionForHR(graph.AddFilter(grabberFilter, "SampleGrabber")); IBaseFilter nullRenderer = (IBaseFilter)(new NullRenderer()); Marshal.ThrowExceptionForHR(graph.AddFilter(nullRenderer, "Null Filter")); Marshal.ThrowExceptionForHR(graphBuilder.RenderStream(null, MediaType.Video, filter, null, grabberFilter)); _mediaEvent = graph as IMediaEventEx; _mediaControl = graph as IMediaControl; Marshal.ReleaseComObject(graphBuilder); _timer = new Timer(50); _timer.Elapsed += TimerElapsed; }