//Size captureResolution) private void SetCaptureResolution(ChannelAnalogic.CaptureFormat captureFormat) { object o = null; int hr = this.captureGraphBuilder.FindInterface(null, //PinCategory.Preview, // Preview pin. MediaType.Video, //null, // Any media type. this.videoCaptureFilter, // Pointer to the capture filter. typeof(IAMStreamConfig).GUID, out o); if (hr >= 0) { IAMStreamConfig amStreamConfig = o as IAMStreamConfig; AMMediaType mediaType; hr = amStreamConfig.GetFormat(out mediaType); if (hr >= 0) { if ((mediaType.majorType == MediaType.Video) && (mediaType.formatType == FormatType.VideoInfo) && (mediaType.formatSize >= Marshal.SizeOf(typeof(VideoInfoHeader))) && (mediaType.formatPtr != IntPtr.Zero)) { VideoInfoHeader videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader)); Size resolution = new Size(videoInfoHeader.BmiHeader.Width, videoInfoHeader.BmiHeader.Height); int framePerSecond = (int)(10000000.0 / videoInfoHeader.AvgTimePerFrame); string mediaSubType = (string)DeviceEnumerator.MediaSubTypeByGUID[mediaType.subType]; if (captureFormat.Resolution == resolution && captureFormat.FramePerSecond == framePerSecond && captureFormat.MediaSubType == mediaSubType) return; } DsUtils.FreeAMMediaType(mediaType); } int iCount = 0, iSize = 0; hr = amStreamConfig.GetNumberOfCapabilities(out iCount, out iSize); // Check the size to make sure we pass in the correct structure. if (iSize == Marshal.SizeOf(typeof(VideoStreamConfigCaps))) { // Use the video capabilities structure. VideoStreamConfigCaps scc = new VideoStreamConfigCaps(); GCHandle gchScc = GCHandle.Alloc(scc, GCHandleType.Pinned); IntPtr pScc = gchScc.AddrOfPinnedObject(); for (int iFormat = 0; iFormat < iCount; iFormat++) { hr = amStreamConfig.GetStreamCaps(iFormat, out mediaType, pScc); if (hr >= 0) { if (mediaType != null && mediaType.majorType == MediaType.Video && mediaType.formatType == FormatType.VideoInfo && mediaType.formatSize >= Marshal.SizeOf(typeof(VideoInfoHeader)) && mediaType.formatPtr != IntPtr.Zero) { VideoInfoHeader videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader)); Size resolution = new Size(videoInfoHeader.BmiHeader.Width, videoInfoHeader.BmiHeader.Height); int framePerSecond = (int)(10000000.0 / videoInfoHeader.AvgTimePerFrame); string mediaSubType = (string)DeviceEnumerator.MediaSubTypeByGUID[mediaType.subType]; if (captureFormat.Resolution == resolution && captureFormat.FramePerSecond == framePerSecond && captureFormat.MediaSubType == mediaSubType) { StopGraph(); hr = amStreamConfig.SetFormat(mediaType); break; } DsUtils.FreeAMMediaType(mediaType); } } } gchScc.Free(); } } }
/// <summary> /// This method returns the capabilities of the current selected video device. /// That is a list of video sizes and a list of frame rates. /// </summary> /// <param name="videoDevice">[in] A <see cref="IBaseFilter"/> thats properties should be received.</param> /// <param name="videoSizes">[out] A <see cref="List{Size}"/> with valid video sizes.</param> /// <param name="frameRates">[out] A <see cref="List{Int32}"/> with valid frame rates.</param> /// <returns><strong>True</strong>, if parsing was successfull, otherwise <strong>false</strong></returns> public static bool GetVideoCaps(IBaseFilter videoDevice, out List<Size> videoSizes, out List<int> frameRates) { int hr; object o; int pinCount; int pinSize; videoSizes = new List<Size>(); frameRates = new List<int>(); if (videoDevice == null) { return false; } // Create the Graph IGraphBuilder localGraphBuilder = (IGraphBuilder)new FilterGraph(); // Create the Capture Graph Builder ICaptureGraphBuilder2 captureGraphBuilder = null; captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); try { // Attach the filter graph to the capture graph hr = captureGraphBuilder.SetFiltergraph(localGraphBuilder); DsError.ThrowExceptionForHR(hr); // Add the Video input device to the graph hr = localGraphBuilder.AddFilter(videoDevice, "video source filter"); DsError.ThrowExceptionForHR(hr); // Find the stream config interface hr = captureGraphBuilder.FindInterface( PinCategory.Capture, MediaType.Video, videoDevice, typeof(IAMStreamConfig).GUID, out o); DsError.ThrowExceptionForHR(hr); IAMStreamConfig videoStreamConfig = o as IAMStreamConfig; if (videoStreamConfig == null) { throw new Exception("Failed to get IAMStreamConfig"); } hr = videoStreamConfig.GetNumberOfCapabilities(out pinCount, out pinSize); DsError.ThrowExceptionForHR(hr); AMMediaType media; // copy out the videoinfoheader VideoStreamConfigCaps caps = new VideoStreamConfigCaps(); IntPtr capsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(VideoStreamConfigCaps))); Marshal.StructureToPtr(caps, capsPtr, false); for (int i = 0; i < pinCount; i++) { hr = videoStreamConfig.GetStreamCaps(i, out media, capsPtr); DsError.ThrowExceptionForHR(hr); Marshal.PtrToStructure(capsPtr, caps); // Get valid framerates int maxRate = (int)(10000000f / caps.MinFrameInterval); int minRate = (int)(10000000f / caps.MaxFrameInterval); // Paranoia check for wrong intialized web cams // which don´t use nano second units, instead using real frame rates if (caps.MinFrameInterval < 100) { minRate = (int)caps.MinFrameInterval; maxRate = (int)caps.MaxFrameInterval; } for (int j = minRate; j <= maxRate; j++) { if (!frameRates.Contains(j)) { frameRates.Add(j); } } // Get valid video sizes if (caps.MinOutputSize != caps.MaxOutputSize && caps.OutputGranularityX != 0) { int count = (caps.MaxOutputSize.Width - caps.MinOutputSize.Width) / caps.OutputGranularityX; for (int j = 0; j <= count; j++) { Size newSize = caps.MinOutputSize; newSize.Width += caps.OutputGranularityX * j; newSize.Height += caps.OutputGranularityY * j; if (!videoSizes.Contains(newSize)) { videoSizes.Add(newSize); } } } else { if (!videoSizes.Contains(caps.MinOutputSize)) { videoSizes.Add(caps.MinOutputSize); } } DsUtils.FreeAMMediaType(media); } Marshal.FreeHGlobal(capsPtr); } catch (Exception ex) { MessageBox.Show(ex.Message); return false; } finally { if (localGraphBuilder != null) { Marshal.ReleaseComObject(localGraphBuilder); localGraphBuilder = null; } if (captureGraphBuilder != null) { Marshal.ReleaseComObject(captureGraphBuilder); captureGraphBuilder = null; } } return true; }