• Advertisement
Sign in to follow this  

[DXSHOW] Get webcam bitmap

This topic is 1519 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

 

Trying to figure out, how to get a bitmap from webcam output.

The problem is in colours. it seems a webcam output is YUV color space and i am not sure, how to display it right as most other examples are not care about that.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DirectShowLib;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
        public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);

        public IGraphBuilder gb;
        public ICaptureGraphBuilder2 cgb;
        public IBaseFilter filter;
        static SampleGrabberCallback cb;
        VideoInfoHeader header;
        static Form1 thisform;



        public class SampleGrabberCallback : ISampleGrabberCB
        {

            int ISampleGrabberCB.SampleCB(Double SampleTime, IMediaSample sample)
            {
                return 0;
            }

            int ISampleGrabberCB.BufferCB( Double SampleTime, IntPtr dataPtr, Int32 BufferLen ) 
            {                  
                Bitmap bitmap = new Bitmap(640, 480, 640*3, PixelFormat.Format24bbp, dataPtr);

                Graphics g = thisform.panel1.CreateGraphics();
                g.DrawImageUnscaled(bitmap, 0, 0, 640, 480);

                return 0;
            }
        }

        public Form1()
        {
            InitializeComponent();
            thisform = this;

            DsDevice[] videoInputDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);            
            object obj = null; Guid iid = typeof(IBaseFilter).GUID;
            videoInputDevices[1].Mon.BindToObject(null, null, ref iid, out obj);
            filter = (IBaseFilter)obj;
            ISampleGrabber grabberFilter = (ISampleGrabber)new SampleGrabber();
            IBaseFilter baseGrabber = (IBaseFilter)grabberFilter;

 

            ((IAMCameraControl)filter).Set(CameraControlProperty.Exposure, 0, CameraControlFlags.Auto);
            

            gb  = (IGraphBuilder) new FilterGraph();
            cgb = (ICaptureGraphBuilder2) new CaptureGraphBuilder2();
            
            cgb.SetFiltergraph(gb);
            

            IEnumPins pins;
            IPin [] inputPin = { null };
            IPin [] outputPin = { null };

            filter.EnumPins(out pins);
            pins.Next(1, outputPin, IntPtr.Zero);

            baseGrabber.EnumPins(out pins);
            pins.Next(1, inputPin, IntPtr.Zero);

            gb.AddFilter(filter, "First Filter");
            gb.AddFilter(baseGrabber, "Grabber Filter");
            gb.Connect(outputPin[0], inputPin[0]);


            grabberFilter.SetBufferSamples(true);

            AMMediaType media = new AMMediaType();
            media.majorType = MediaType.Video;
            media.subType = MediaSubType.RGB24;
            media.formatType = FormatType.VideoInfo;

            grabberFilter.SetMediaType(media);
            grabberFilter.GetConnectedMediaType(media);
            header = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader)); 


            cb = new SampleGrabberCallback();          

            grabberFilter.SetCallback(cb, 1);


            cgb.RenderStream(PinCategory.Preview, MediaType.Video, filter, null, null);
            ((IVideoWindow)gb).put_Owner(this.panel1.Handle);
            ((IVideoWindow)gb).put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren);
            ((IVideoWindow)gb).put_Visible(OABool.True);
            ((IVideoWindow)gb).SetWindowPosition(0, 0, this.panel1.Width, this.panel1.Height);
            ((IMediaControl)gb).Run();
        }

        private void OnResize(object sender, EventArgs e)
        {
            ((IVideoWindow)gb).SetWindowPosition(0, 0, this.panel1.Width, this.panel1.Height);
        }
    }
}

This is my code, it enumerate video devices ( my default device is number 1, you should use 0, if you have only one device ), SampleGrabber calls callback function and i can get a buffer there.

 

I tried most formats Format24bbp, Format16bpp565 .. and .. ok, if it's YUV, i should convert it, but i though i can just specify type in mediatype as examples are doing it.

 

I also attached full source with directshownet library. if someone has a time to check, i will be very happy as i am trying to figure it out whole a day, reading tutorials, samples ... smile.png

 

Thank you very much

Edited by wh1sp3rik

Share this post


Link to post
Share on other sites
Advertisement

I just got an answer on StackOverflow.

 

I set up SampleGrabber filter too late. I should set it up before connecting and that was the problem.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement