示例#1
0
        /// <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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
            }
        }