IGraphBuilder使用ColorConverter

时间:2012-07-26 13:12:23

标签: c# webcam directshow directshow.net

我尝试使用此代码来获取我的照片:

            IGraphBuilder _graph = null;
            ISampleGrabber _grabber = null;
            IBaseFilter _sourceObject = null;
            IBaseFilter _grabberObject = null;
            IMediaControl _control = null;

            // Create the main graph
            _graph = Activator.CreateInstance(Type.GetTypeFromCLSID(FilterGraph)) as IGraphBuilder;

            // Create the webcam source
            _sourceObject = FilterInfo.CreateFilter(_monikerString);

            // Create the grabber
            _grabber = Activator.CreateInstance(Type.GetTypeFromCLSID(SampleGrabber)) as ISampleGrabber;
            _grabberObject = _grabber as IBaseFilter;

            // Add the source and grabber to the main graph
            _graph.AddFilter(_sourceObject, "source");
            _graph.AddFilter(_grabberObject, "grabber");

            IPin pin = _sourceObject.GetPin(PinDirection.Output, 0);

            IAMStreamConfig streamConfig = pin as IAMStreamConfig;
            int count = 0, size = 0;
            streamConfig.GetNumberOfCapabilities(out count, out size);

            int width = 0, height = 0;
            AMMediaType mediaType = null;
            AMMediaType mediaTypeCandidate = null;
            for(int index = 0; index < count; index++) {
                VideoStreamConfigCaps scc = new VideoStreamConfigCaps();
                int test = streamConfig.GetStreamCaps(index, out mediaTypeCandidate, scc);
                if(mediaTypeCandidate.MajorType == MediaTypes.Video && mediaTypeCandidate.SubType == MediaSubTypes.YUY2) {
                    VideoInfoHeader header = (VideoInfoHeader)Marshal.PtrToStructure(mediaTypeCandidate.FormatPtr, typeof(VideoInfoHeader));

                    if(header.BmiHeader.Width == 1280 && header.BmiHeader.Height == 720) {
                        width = header.BmiHeader.Width;
                        height = header.BmiHeader.Height;
                        if(mediaType != null)
                            mediaType.Dispose();
                        mediaType = mediaTypeCandidate;
                    } else
                        mediaTypeCandidate.Dispose();
                } else
                    mediaTypeCandidate.Dispose();
            }

            streamConfig.SetFormat(mediaType);

它有效,但我没有看到由此代码生成的图像:

uint pcount = (uint)(_capGrabber.Width * _capGrabber.Height * PixelFormats.Bgr32.BitsPerPixel / 8);

                    // Create a file mapping
                    _section = CreateFileMapping(new IntPtr(-1), IntPtr.Zero, 0x04, 0, pcount, null);
                    _map = MapViewOfFile(_section, 0xF001F, 0, 0, pcount);

                    // Get the bitmap
                    BitmapSource = Imaging.CreateBitmapSourceFromMemorySection(_section, _capGrabber.Width,
                        _capGrabber.Height, PixelFormats.Bgr32, _capGrabber.Width * PixelFormats.Bgr32.BitsPerPixel / 8, 0) as InteropBitmap;
                    _capGrabber.Map = _map;

                    // Invoke event
                    if (NewBitmapReady != null)
                    {
                        NewBitmapReady(this, null);
                    }

因为SubMediaTyp是YUY2。如何在此代码中添加转换器?我已经阅读了一些关于ColorConvert的内容,可以将其添加到IGraphBuilder中。这有什么作用?

1 个答案:

答案 0 :(得分:0)

我不希望CreateBitmapSourceFromMemorySection接受除flavors of RGB以外的任何其他内容。它更不可能接受YUY2媒体类型,因此您需要DirectShow管道将视频流转换为RGB,然后再将其导出为托管位图/成像对象。

为实现此目的,您通常会将Sample Grabber过滤器初始化为24位RGB子类型,并让DirectShow自动提供必要的转换器。

请在此处查看详细说明和代码段:DirectShow: Examples for Using SampleGrabber for Grabbing a Frame and...

media.majorType    = MediaType.Video;
media.subType    = MediaSubType.RGB24;
media.formatPtr = IntPtr.Zero;
hr = sampGrabber.SetMediaType(media);