Jump to content
  • Advertisement
Sign in to follow this  
wh1sp3rik

[DXSHOW] Get webcam bitmap

This topic is 1609 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
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!