0

I try to use this code to get pictures of my cam:

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

And it works but i do not see the Image which is generated by this code:

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

Because the SubMediaTyp is YUY2. How can i add a converter to this code? I have read something about a ColorConvert, which can be added to the IGraphBuilder. How does that work?

Roman R.
  • 68,205
  • 6
  • 94
  • 158
bobschi
  • 325
  • 1
  • 3
  • 13

1 Answers1

0

I would not expect CreateBitmapSourceFromMemorySection to accept anything else than flavors of RGB. Even more unlikely that it accepts YUY2 media type, so you need the DirectShow pipeline to convert video stream to RGB before you export it as a managed bitmap/imaging object.

To achieve this, you typically add Sample Grabber filter initialized to 24-bit RGB subtype and let DirectShow provide necessary converters automatically.

See detailed explanation and code snippets here: 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);
Roman R.
  • 68,205
  • 6
  • 94
  • 158
  • Thank you so much. You saved my weekend ;-) Simply set the MediaType of the grabber and it works. – bobschi Jul 27 '12 at 06:59