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)] internalinterface IAMStreamConfig { [PreserveSig] int SetFormat([In, MarshalAs(UnmanagedType.LPStruct)] AMMediaType pmt); [PreserveSig] int GetFormat([Out] out IntPtr pmt); [PreserveSig] int GetNumberOfCapabilities( [Out] outint piCount, [Out] outint 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:
privatevoid 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 timesint 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