/// <summary> /// Gets the first pin of the specified direction that supports specified media types. /// /// If this function finds a matching pin, it returns an IPin interface pointer /// with an outstanding reference count. The caller is responsible for releasing the interface. /// </summary> /// <param name="pFilter">Filter</param> /// <param name="pinDir">Pin direction</param> /// <param name="mediaTypes">Supported media types</param> /// <param name="searchConnected">Search connected pins in addition to disconnected ones</param> /// <param name="disconnect">Disconnect a connected pin if it satifies the conditions and return it</param> /// <returns></returns> public static IPin GetPin(IBaseFilter pFilter, PinDirection pinDir, Guid[] mediaTypes, bool searchConnected, bool disconnect) { IPin pPin = null; int nSkip = 0; while ((pPin = GetPin(pFilter, pinDir, false, nSkip)) != null) { if (mediaTypes.Any(t => IsMediaTypeSupported(pPin, t) == 0)) { break; } nSkip++; Marshal.ReleaseComObject(pPin); pPin = null; } if (pPin == null && searchConnected) { // let's try connected pins nSkip = 0; while ((pPin = GetPin(pFilter, pinDir, true, nSkip)) != null) { if (mediaTypes.Any(t => IsMediaTypeSupported(pPin, t) == 0)) { if (disconnect) { FilterInfo fInfo = new FilterInfo(); var hr = pFilter.QueryFilterInfo(out fInfo); if (DsHlp.SUCCEEDED(hr)) { // The FILTER_INFO structure holds a pointer to the Filter Graph // Manager, with a reference count that must be released. if (fInfo.pGraph != null) { Disconnect(fInfo.pGraph, pPin); Marshal.ReleaseComObject(fInfo.pGraph); } } } break; } nSkip++; Marshal.ReleaseComObject(pPin); pPin = null; } } return(pPin); }
public static Guid GetMediaType(IPin pPin) { Guid mediaType = Guid.Empty; IEnumMediaTypes pEnumTypes; int cFetched; int hr = pPin.EnumMediaTypes(out pEnumTypes); if (DsHlp.SUCCEEDED(hr)) { IntPtr ptr; if (pEnumTypes.Next(1, out ptr, out cFetched) == DsHlp.S_OK) { AMMediaType mt = (AMMediaType)Marshal.PtrToStructure(ptr, typeof(AMMediaType)); mediaType = mt.majorType; // free the allocated memory FreeFormatBlock(ptr); Marshal.FreeCoTaskMem(ptr); } Marshal.ReleaseComObject(pEnumTypes); } return(mediaType); }
public static void RemoveRedundantFilters(IBaseFilter sourceFilter, IGraphBuilder graphBuilder) { IEnumFilters pEnumFilters = null; IBaseFilter pFilter = null; int cFetched; int hr; bool bCallAgain = false; // get information about the source filter (its name) FilterInfo fSourceInfo = new FilterInfo(); if (sourceFilter != null) { hr = sourceFilter.QueryFilterInfo(out fSourceInfo); if (DsHlp.SUCCEEDED(hr)) { if (fSourceInfo.pGraph != null) { Marshal.ReleaseComObject(fSourceInfo.pGraph); } } else { fSourceInfo.achName = null; } } // let's start enumerating filters hr = graphBuilder.EnumFilters(out pEnumFilters); if (DsHlp.FAILED(hr)) { return; } while ((pEnumFilters.Next(1, out pFilter, out cFetched) == DsHlp.S_OK)) { FilterInfo fInfo = new FilterInfo(); hr = pFilter.QueryFilterInfo(out fInfo); if (DsHlp.FAILED(hr)) { Marshal.ReleaseComObject(pFilter); continue; // don't touch this one } // The FILTER_INFO structure holds a pointer to the Filter Graph // Manager, with a reference count that must be released. if (fInfo.pGraph != null) { Marshal.ReleaseComObject(fInfo.pGraph); } if (fInfo.achName == null || fSourceInfo.achName == null) { Marshal.ReleaseComObject(pFilter); continue; } if (fInfo.achName == fSourceInfo.achName) // source filter { Marshal.ReleaseComObject(pFilter); continue; } IPin pPin = DsUtils.GetPin(pFilter, PinDirection.Input, true, 0); if (pPin == null) { // this filter does not have connected input pins graphBuilder.RemoveFilter(pFilter); Marshal.ReleaseComObject(pFilter); bCallAgain = true; break; } else { // this filter is connected, let's try another one Marshal.ReleaseComObject(pPin); Marshal.ReleaseComObject(pFilter); } } Marshal.ReleaseComObject(pEnumFilters); if (bCallAgain) { RemoveRedundantFilters(sourceFilter, graphBuilder); } }