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;
        }