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)]internalinterface IAMStreamConfig { [PreserveSig]int SetFormat([In, MarshalAs(UnmanagedType.LPStruct)] AMMediaType pmt); [PreserveSig] int GetFormat([Out] out AMMediaType pmt); [PreserveSig] int GetNumberOfCapabilities(outint piCount, outint piSize); [PreserveSig] int GetStreamCaps( [In] int iIndex, [Out] out AMMediaType ppmt, [In] VideoStreamConfigCaps pSCC ); } [StructLayout(LayoutKind.Sequential)] publicclass VideoStreamConfigCaps {public Guid guid;public AnalogVideoStandard VideoStandard;public Size InputSize;public Size MinCroppingSize;public Size MaxCroppingSize;publicint CropGranularityX;publicint CropGranularityY;publicint CropAlignX;publicint CropAlignY;public Size MinOutputSize;public Size MaxOutputSize;publicint OutputGranularityX;publicint OutputGranularityY;publicint StretchTapsX;publicint StretchTapsY;publicint ShrinkTapsX;publicint ShrinkTapsY;publiclong MinFrameInterval;publiclong MaxFrameInterval;publicint MinBitsPerSecond;publicint MaxBitsPerSecond; } [Flags]publicenum 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>privatevoid 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 timesint 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