private WebcamFormat[] GetWebcamFormats(string webcamId, bool filter, bool exact, int minWidth, int minHeight, float minFrameRate) { List <WebcamFormat> list = null; HResult result = GetMediaSource(webcamId, out IMFMediaSource source); if (result == Player.NO_ERROR) { result = MFExtern.MFCreateSourceReaderFromMediaSource(source, null, out IMFSourceReader reader); if (result == Player.NO_ERROR) { HResult readResult = Player.NO_ERROR; int streamIndex = 0; int typeIndex = 0; float frameRate = 0; bool match; list = new List <WebcamFormat>(250); while (readResult == Player.NO_ERROR) { readResult = reader.GetNativeMediaType(streamIndex, typeIndex, out IMFMediaType type); if (readResult == Player.NO_ERROR) { MFExtern.MFGetAttributeRatio(type, MFAttributesClsid.MF_MT_FRAME_RATE, out int num, out int denum); if (denum > 0) { frameRate = (float)num / denum; } MFExtern.MFGetAttributeRatio(type, MFAttributesClsid.MF_MT_FRAME_SIZE, out int width, out int height); match = true; if (filter) { if (exact) { if ((minWidth != -1 && width != minWidth) || (minHeight != -1 && height != minHeight) || (minFrameRate != -1 && frameRate != minFrameRate)) { match = false; } } else if ((minWidth != -1 && width < minWidth) || (minHeight != -1 && height < minHeight) || (minFrameRate != -1 && frameRate < minFrameRate)) { match = false; } } if (match && !FormatExists(list, width, height, frameRate)) { list.Add(new WebcamFormat(streamIndex, typeIndex, width, height, frameRate)); } typeIndex++; Marshal.ReleaseComObject(type); } // read formats of 1 track (stream) only - can't switch tracks (?) //else if (readResult == HResult.MF_E_NO_MORE_TYPES) //{ // readResult = Player.NO_ERROR; // streamIndex++; // typeIndex = 0; //} } if (reader != null) { Marshal.ReleaseComObject(reader); } } if (source != null) { Marshal.ReleaseComObject(source); } } _base._lastError = result; return((list == null || list.Count == 0) ? null : list.ToArray()); }