Changing Webcam resolution

May 26, 2009 at 3:30 PM

Hi!

First of all, you made a great work whith your code.

I'm wondering how to change the webcam resolution, in fact I have a webcam which is able to display 960x720 and whith the CapPlayer, I can only show 640x480.

I tried to change

header.BmiHeader.Width = 960;

header.BmiHeader.Height = 720;

but this didn't do what I want.

 

Thanks

Aug 13, 2010 at 2:06 PM

Hi,

Have you been able to change the resolution of the webcam ?

Thanks

Nikita

Aug 16, 2010 at 3:57 PM
Hi,
Yes I did it, what you have to do is to access to the capture pin, change resolution, then apply the change and it's done





> Message du 13/08/10 à 15h06
> De : "Nikita0511" <notifications@codeplex.com>
> A : cedric.gattuso@voila.fr
> Copie à :
> Objet : Re: Changing Webcam resolution [wpfcap:57482]
>
> From: Nikita0511
>
> Hi,Have you been able to change the resolution of the webcam ?ThanksNikita
>
>

____________________________________________________

Tout pour bien s'occuper cet été : les festivals et les cinémas en plein air sur http://actu.voila.fr/evenementiel/VacancesEte2010/
Aug 17, 2010 at 8:10 AM
Edited Aug 17, 2010 at 8:12 AM

Thank you, I will try tomorrow

Aug 18, 2010 at 2:21 PM

Infact, I don't understand what is the capture pin.

Aug 18, 2010 at 2:40 PM
In your webcam, you generally have two pins : one is the capture pin, second is the preview pin (sometimes you have only one pin, or thre with the sound pin).

Thanks to IPin you can control it and change the resolution



> Message du 18/08/10 à 15h23
> De : "Nikita0511" <notifications@codeplex.com>
> A : cedric.gattuso@voila.fr
> Copie à :
> Objet : Re: Changing Webcam resolution [wpfcap:57482]
>
> From: Nikita0511
>
> Infact, I don't understand what is the capture pin.
>
>

____________________________________________________

Suivez toute l'actualité de Secret Story, retrouvez les dépêches, les photos et les vidéos sur http://people.voila.fr/evenementiel/secret-story2010/
Dec 14, 2010 at 8:43 PM

First of all, nice work on the code. It's simple comparing to other webcam capture code out there.

When i run the sample, the webcam is upside down. How do you turn it back?

To gatzo, What is IPin and how do you use it?

Thanks

JC

Jun 9, 2011 at 2:55 PM

can you give a sample code ?

I try  IPin.EnumMediaTypes(mediatypes);

get a list of media types then setmedia(mediatype) but not seem to work.

I'm just a beginer in directshow, dont know anything about ds

Im graphedit, I see that my webcam can only output RGB24, but the code sample graper want RGB32 so the colorspaceconverter filter auto add up

 

after colorspaceconverter addup I check output pin only resolution of 320x240 available, other resolutions gone.

thanks,

Dec 10, 2011 at 10:00 PM

Hi,

I know this discussion is old, but I'm trying to set the resolution of my camera and not succeeding in it.
I have a Full HD camera, getting only 640*480 though.

I am not understanding what gatzo means by Pins and IPin, how to implement it.

So, could someone please help?

 

Thanks!

May 14, 2012 at 8:40 AM

Hi,

I know this discussion is old, but I'm trying to set the resolution of my camera and not succeeding in it.

I am not understanding what you means by Pins and IPin, how to implement it.

can you give a sample code ?

May 14, 2012 at 8:41 AM
gatzo wrote:
In your webcam, you generally have two pins : one is the capture pin, second is the preview pin (sometimes you have only one pin, or thre with the sound pin).

Thanks to IPin you can control it and change the resolution



> Message du 18/08/10 à 15h23
> De : "Nikita0511" <notifications@codeplex.com>
> A : cedric.gattuso@voila.fr
> Copie à :
> Objet : Re: Changing Webcam resolution [wpfcap:57482]
>
> From: Nikita0511
>
> Infact, I don't understand what is the capture pin.
>
>

____________________________________________________

Suivez toute l'actualité de Secret Story, retrouvez les dépêches, les photos et les vidéos sur http://people.voila.fr/evenementiel/secret-story2010/

 

Hi,

I know this discussion is old, but I'm trying to set the resolution of my camera and not succeeding in it.

I am not understanding what you means by Pins and IPin, how to implement it.

can you give a sample code ?

Jul 6, 2012 at 7:51 AM

Has anyone found how to change the web cam resolution? 

Oct 24, 2012 at 7:13 PM
Edited Oct 24, 2012 at 7:14 PM

I played around the hole day to get the cam working for a higher resolution than 640x400, without any success - I'll stop right now to waste more time for this problem. It seems that it is not possible to get higher resolution with my and some other notebook web cams.

With the help of this post http://blog.catenalogic.com/post/2009/01/08/WPF-Webcam-Control-part-2.aspx#id_a96da4fb-b815-4809-b334-1c33dbf1f043 I added and modified the code.

I've added to the CapInterface.cs:

 

[ComVisible(true), ComImport, Guid("C6E13340-30AC-11D0-A18C-00A0C9118956"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IAMStreamConfig
    {
        [PreserveSig]
        int SetFormat([In, MarshalAs(UnmanagedType.LPStruct)] AMMediaType pmt);

        [PreserveSig]
        int GetFormat([Out] out IntPtr pmt);

        [PreserveSig]
        int GetNumberOfCapabilities(
        [Out] out int piCount,
        [Out] out int piSize);

        [PreserveSig]
        int GetStreamCaps(
        [In] int iIndex,
        [Out] out IntPtr ppmt,
        [In] IntPtr pSCC
        );
    }

 

And at the CapDevice.cs I replaced a part of the method RunWorker:

private void RunWorker()
        {
            try
            {
                IGraphBuilder _graph = null;
                ISampleGrabber _grabber = null;
                IBaseFilter _sourceObject = null;
                IBaseFilter _grabberObject = null;
                IMediaControl _control = null;

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

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

                // Changed
                AMMediaType mediaType = new AMMediaType();
                //using (AMMediaType mediaType = new AMMediaType())
                {
                    mediaType.MajorType = MediaTypes.Video;
                    mediaType.SubType = MediaSubTypes.RGB32;

                    // Added changes start
                    IEnumPins _enumPin;
                    _sourceObject.EnumPins(out _enumPin);
                    IPin[] _IPP = new IPin[3];
                    int pt = -1;
                    _enumPin.Next(3, _IPP, out pt);

                    IAMStreamConfig streamConfig = (IAMStreamConfig)_IPP[0];
                    streamConfig.GetFormat(out mediaType.FormatPtr);

                    VideoInfoHeader header = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.FormatPtr, typeof(VideoInfoHeader));
                    // Change this values will cause a noise or flicker, tried different solutions
                    header.BmiHeader.Width = 640;
                    header.BmiHeader.Height = 400;

                    Marshal.StructureToPtr(header, mediaType.FormatPtr, false);
                    streamConfig.SetFormat(mediaType);
                    // Added changes stop

                    _grabber.SetMediaType(mediaType);

                    if (_graph.Connect(_sourceObject.GetPin(PinDirection.Output, 0), _grabberObject.GetPin(PinDirection.Input, 0)) >= 0)
                    {
                        if (_grabber.GetConnectedMediaType(mediaType) == 0)
                        {
                            // During startup, this code can be too fast, so try at least 3 times
                            int retryCount = 0;
                            bool succeeded = false;

                            while ((retryCount < 3) && !succeeded)
                            {
                                // Tried again
                                retryCount++;

                                try
                                {
                                    // Header already defined
//VideoInfoHeader header = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.FormatPtr, typeof(VideoInfoHeader)); ...

 

If somebody gets it working please write a post here how to fix the resolution problem, thank you very much.

Kind regards

Nov 5, 2012 at 5:07 AM

I managed to change the Resolution but it does not work all the time, depending on the Webcam. It seems that it falls back to 640x480 when it does not work. And when it works, the camera is seems to be slow updating the picture on the screen. I would like to see more discussion here and hopefully I can get a fix for my problem too.

 

Add the following Interface and Classes to the end of you CapDevice.cs or Anywhere in your project then reference them

 

 

[ComImport, System.Security.SuppressUnmanagedCodeSecurity,
Guid("C6E13340-30AC-11d0-A18C-00A0C9118956"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IAMStreamConfig
    {
        [PreserveSig]
        int SetFormat([In, MarshalAs(UnmanagedType.LPStruct)] AMMediaType pmt);

        [PreserveSig]
        int GetFormat([Out] out AMMediaType pmt);

        [PreserveSig]
        int GetNumberOfCapabilities(out int piCount, out int piSize);

        [PreserveSig]
        int GetStreamCaps(
            [In] int iIndex,
            [Out] out AMMediaType ppmt,
            [In] VideoStreamConfigCaps pSCC
            );
    }

    [StructLayout(LayoutKind.Sequential)]
    public class VideoStreamConfigCaps
    {
        public Guid guid;
        public AnalogVideoStandard VideoStandard;
        public Size InputSize;
        public Size MinCroppingSize;
        public Size MaxCroppingSize;
        public int CropGranularityX;
        public int CropGranularityY;
        public int CropAlignX;
        public int CropAlignY;
        public Size MinOutputSize;
        public Size MaxOutputSize;
        public int OutputGranularityX;
        public int OutputGranularityY;
        public int StretchTapsX;
        public int StretchTapsY;
        public int ShrinkTapsX;
        public int ShrinkTapsY;
        public long MinFrameInterval;
        public long MaxFrameInterval;
        public int MinBitsPerSecond;
        public int MaxBitsPerSecond;
    }
    [Flags]
    public enum AnalogVideoStandard
    {
        None = 0x00000000,
        NTSC_M = 0x00000001,
        NTSC_M_J = 0x00000002,
        NTSC_433 = 0x00000004,
        PAL_B = 0x00000010,
        PAL_D = 0x00000020,
        PAL_G = 0x00000040,
        PAL_H = 0x00000080,
        PAL_I = 0x00000100,
        PAL_M = 0x00000200,
        PAL_N = 0x00000400,
        PAL_60 = 0x00000800,
        SECAM_B = 0x00001000,
        SECAM_D = 0x00002000,
        SECAM_G = 0x00004000,
        SECAM_H = 0x00008000,
        SECAM_K = 0x00010000,
        SECAM_K1 = 0x00020000,
        SECAM_L = 0x00040000,
        SECAM_L1 = 0x00080000,
        PAL_N_COMBO = 0x00100000,

        NTSCMask = 0x00000007,
        PALMask = 0x00100FF0,
        SECAMMask = 0x000FF000
    }

 

 

Then change your RunWorker() to the following

 

 

        /// <summary>
        /// Worker thread that captures the images
        /// </summary>
        private void RunWorker()
        {
            try
            {
                // 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");

                using (AMMediaType mediaType = new AMMediaType())
                {
                    mediaType.MajorType = MediaTypes.Video;
                    mediaType.SubType = MediaSubTypes.RGB32;
                    _grabber.SetMediaType(mediaType);

                    IEnumPins _enumPin;
                    _sourceObject.EnumPins(out _enumPin);
                    IPin[] _IPP = new IPin[3];
                    int pt = -1;
                    _enumPin.Next(3, _IPP, out pt);

                    IAMStreamConfig st = (IAMStreamConfig)_IPP[0];

                    AMMediaType med = new AMMediaType();
                    st.GetFormat(out med);
                    VideoInfoHeader head = (VideoInfoHeader)Marshal.PtrToStructure(med.FormatPtr, typeof(VideoInfoHeader));

                    //head.BmiHeader.Width = 1280;
                    //head.BmiHeader.Height = 720;

                    head.BmiHeader.Width = 1600;
                    head.BmiHeader.Height = 900;

                    Marshal.StructureToPtr(head, med.FormatPtr, false);
                    st.SetFormat(med);

                    if (_graph.Connect(_sourceObject.GetPin(PinDirection.Output, 0), _grabberObject.GetPin(PinDirection.Input, 0)) >= 0)
                    {
                        if (_grabber.GetConnectedMediaType(mediaType) == 0)
                        {
                            // During startup, this code can be too fast, so try at least 3 times
                            int retryCount = 0;
                            bool succeeded = false;
                            while ((retryCount < 3) && !succeeded)
                            {
                                // Tried again
                                retryCount++;

                                try
                                {
                                    // Retrieve the grabber information
                                    VideoInfoHeader header = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.FormatPtr, typeof(VideoInfoHeader));
                                    _capGrabber.Width = header.BmiHeader.Width;
                                    _capGrabber.Height = header.BmiHeader.Height;
                                    logger.Info("Camera Resolution is set to " + header.BmiHeader.Height + " x " + header.BmiHeader.Width);
                                    // Succeeded
                                    succeeded = true;
                                }
                                catch (Exception retryException)
                                {
                                    // Trace
                                    Trace.TraceInformation("Failed to retrieve the grabber information, tried {0} time(s)", retryCount);
                                    logger.Fatal("Failed to retrieve the grabber information: " + retryException.Message);
                                    // Sleep
                                    Thread.Sleep(50);
                                }
                            }
                        }
                    }
                    _graph.Render(_grabberObject.GetPin(PinDirection.Output, 0));
                    _grabber.SetBufferSamples(false);
                    _grabber.SetOneShot(false);
                    _grabber.SetCallback(_capGrabber, 1);

                    // Get the video window
                    IVideoWindow wnd = (IVideoWindow)_graph;
                    wnd.put_AutoShow(false);
                    wnd = null;

                    // Create the control and run
                    _control = (IMediaControl)_graph;
                    _control.Run();

                    // Wait for the stop signal
                   // while (!_stopSignal.WaitOne(10, true))
                    //{
                        //Thread.Sleep(10);
                    //}
                    _stopSignal.WaitOne();
                    // Stop when ready
                    _control.StopWhenReady();
                }
            }
            catch (Exception ex)
            {
                // Trace
                Trace.WriteLine(ex);
            }
            finally
            {
                // Clean up
                Release();
            }
        }

 

I hope that helps

 

Cheers

Dec 20, 2013 at 11:50 AM
Not working for me Alabri. Actually it is not working anymore.

I always get the message on the lines:

"Camera Resolution is set to " + header.BmiHeader.Height + " x " + header.BmiHeader.Width
and
"Failed to retrieve the grabber information, tried {0} time(s)", retryCount)