コード例 #1
0
        /// <summary>
        /// Checks if the pin connections can be kept, or if a graph rebuilding is necessary.
        /// </summary>
        /// <param name="baseFilter">Filter to check</param>
        /// <returns>True if graph needs to be rebuilt</returns>
        private static bool GraphNeedsRebuild(IBaseFilter baseFilter)
        {
            IEnumPins pinEnum;
            int       hr = baseFilter.EnumPins(out pinEnum);

            if (hr != 0 || pinEnum == null)
            {
                return(true);
            }
            IPin[] pins       = new IPin[1];
            IntPtr ptrFetched = Marshal.AllocCoTaskMem(4);

            for (; ;)
            {
                hr = pinEnum.Next(1, pins, ptrFetched);
                if (hr != 0 || Marshal.ReadInt32(ptrFetched) == 0)
                {
                    break;
                }
                try
                {
                    IPin other;
                    if (pins[0].ConnectedTo(out other) == 0 && other != null)
                    {
                        try
                        {
                            PinInfo pinInfo;
                            pins[0].QueryPinInfo(out pinInfo);
                            FilterInfo filterInfo = FilterGraphTools.QueryFilterInfoAndFree(pinInfo.filter);
                            try
                            {
                                if (!QueryConnect(pins[0], other))
                                {
                                    ServiceRegistration.Get <ILogger>().Info("Graph needs a rebuild. Filter: {0}, Pin: {1}", filterInfo.achName, pinInfo.name);
                                    return(true);
                                }
                            }
                            finally
                            {
                                FilterGraphTools.FreePinInfo(pinInfo);
                            }
                        }
                        finally
                        {
                            Marshal.ReleaseComObject(other);
                        }
                    }
                }
                finally
                {
                    Marshal.ReleaseComObject(pins[0]);
                }
            }
            Marshal.ReleaseComObject(pinEnum);
            Marshal.FreeCoTaskMem(ptrFetched);
            ServiceRegistration.Get <ILogger>().Info("Graph does not need a rebuild");
            return(false);
        }
コード例 #2
0
        /// <summary>
        /// QueryConnect checks if two Pins can be connected.
        /// </summary>
        /// <param name="pin">Pin 1</param>
        /// <param name="other">Pin 2</param>
        /// <returns>True if they accept connection</returns>
        static bool QueryConnect(IPin pin, IPin other)
        {
            IEnumMediaTypes enumTypes;
            int             hr = pin.EnumMediaTypes(out enumTypes);

            if (hr != 0 || enumTypes == null)
            {
                return(false);
            }

            int    count      = 0;
            IntPtr ptrFetched = Marshal.AllocCoTaskMem(4);

            try
            {
                for (; ;)
                {
                    AMMediaType[] types = new AMMediaType[1];
                    hr = enumTypes.Next(1, types, ptrFetched);
                    if (hr != 0 || Marshal.ReadInt32(ptrFetched) == 0)
                    {
                        break;
                    }

                    count++;
                    try
                    {
                        if (other.QueryAccept(types[0]) == 0)
                        {
                            return(true);
                        }
                    }
                    finally
                    {
                        FilterGraphTools.FreeAMMediaType(types[0]);
                    }
                }
                PinInfo info;
                PinInfo infoOther;
                pin.QueryPinInfo(out info);
                other.QueryPinInfo(out infoOther);
                ServiceRegistration.Get <ILogger>().Info("Pins {0} and {1} do not accept each other. Tested {2} media types", info.name, infoOther.name, count);
                FilterGraphTools.FreePinInfo(info);
                FilterGraphTools.FreePinInfo(infoOther);
                return(false);
            }
            finally
            {
                Marshal.FreeCoTaskMem(ptrFetched);
            }
        }
コード例 #3
0
        /// <summary>
        /// Disconnects a single Pin.
        /// </summary>
        /// <param name="graphBuilder">IGraphBuilder</param>
        /// <param name="pin">Pin to disconnect</param>
        /// <returns>True if successful</returns>
        bool DisconnectPin(IGraphBuilder graphBuilder, IPin pin)
        {
            IntPtr other_ptr;
            int    hr = pin.ConnectedTo(out other_ptr);
            bool   allDisconnected = true;

            if (hr == 0 && other_ptr != IntPtr.Zero)
            {
                IPin    other = Marshal.GetObjectForIUnknown(other_ptr) as IPin;
                PinInfo info;
                pin.QueryPinInfo(out info);
                ServiceRegistration.Get <ILogger>().Info("Disconnecting pin {0}", info.name);
                FilterGraphTools.FreePinInfo(info);

                other.QueryPinInfo(out info);
                if (!DisconnectAllPins(graphBuilder, info.filter))
                {
                    allDisconnected = false;
                }

                FilterGraphTools.FreePinInfo(info);

                hr = pin.Disconnect();
                if (hr != 0)
                {
                    allDisconnected = false;
                    ServiceRegistration.Get <ILogger>().Error("Error disconnecting: {0:x}", hr);
                }
                hr = other.Disconnect();
                if (hr != 0)
                {
                    allDisconnected = false;
                    ServiceRegistration.Get <ILogger>().Error("Error disconnecting other: {0:x}", hr);
                }
                Marshal.ReleaseComObject(other);
            }
            else
            {
                ServiceRegistration.Get <ILogger>().Info("  Not connected");
            }
            return(allDisconnected);
        }
コード例 #4
0
        /// <summary>
        /// Disconnects all pins of all filters in graph.
        /// </summary>
        /// <param name="graphBuilder">IGraphBuilder</param>
        /// <param name="filter">Current IBaseFilter in graph</param>
        bool DisconnectAllPins(IGraphBuilder graphBuilder, IBaseFilter filter)
        {
            IEnumPins pinEnum;
            int       hr = filter.EnumPins(out pinEnum);

            if (hr != 0 || pinEnum == null)
            {
                return(false);
            }
            FilterInfo info = FilterGraphTools.QueryFilterInfoAndFree(filter);

            ServiceRegistration.Get <ILogger>().Info("Disconnecting all pins from filter {0}", info.achName);
            bool   allDisconnected = true;
            IntPtr ptrFetched      = Marshal.AllocCoTaskMem(4);

            for (; ;)
            {
                IPin[] pins = new IPin[1];

                hr = pinEnum.Next(1, pins, ptrFetched);
                if (hr != 0 || Marshal.ReadInt32(ptrFetched) == 0)
                {
                    break;
                }
                PinInfo pinInfo;
                pins[0].QueryPinInfo(out pinInfo);
                if (pinInfo.dir == PinDirection.Output)
                {
                    if (!DisconnectPin(graphBuilder, pins[0]))
                    {
                        allDisconnected = false;
                    }
                }
                FilterGraphTools.FreePinInfo(pinInfo);
                Marshal.ReleaseComObject(pins[0]);
            }
            Marshal.ReleaseComObject(pinEnum);
            Marshal.FreeCoTaskMem(ptrFetched);
            return(allDisconnected);
        }
コード例 #5
0
        /// <summary>
        /// QueryConnect checks if two Pins can be connected.
        /// </summary>
        /// <param name="pin">Pin 1</param>
        /// <param name="other">Pin 2</param>
        /// <returns>True if they accept connection</returns>
        static bool QueryConnect(IPin pin, IPin other)
        {
            var pin1     = new DSPin(pin);
            var pinOther = new DSPin(other);

            foreach (var mediaType in pin1.MediaTypes)
            {
                if (pinOther.IsAccepted(mediaType))
                {
                    return(true);
                }
            }

            PinInfo info;
            PinInfo infoOther;

            pin.QueryPinInfo(out info);
            other.QueryPinInfo(out infoOther);
            ServiceRegistration.Get <ILogger>().Info("Pins {0} and {1} do not accept each other. Tested {2} media types", info.name, infoOther.name, pin1.MediaTypes.Count);
            FilterGraphTools.FreePinInfo(info);
            FilterGraphTools.FreePinInfo(infoOther);
            return(false);
        }
コード例 #6
0
        /// <summary>
        /// Reconnects all filters in graph.
        /// </summary>
        /// <param name="graphBuilder">IGraphBuilder</param>
        /// <param name="filter">Current IBaseFilter in graph</param>
        static void ReConnectAll(IGraphBuilder graphBuilder, IBaseFilter filter)
        {
            IEnumPins  pinEnum;
            FilterInfo info       = FilterGraphTools.QueryFilterInfoAndFree(filter);
            IntPtr     ptrFetched = Marshal.AllocCoTaskMem(4);
            int        hr         = filter.EnumPins(out pinEnum);

            if ((hr == 0) && (pinEnum != null))
            {
                ServiceRegistration.Get <ILogger>().Info("got pins");
                IPin[] pins = new IPin[1];
                int    iFetched;
                int    iPinNo = 0;
                do
                {
                    // Get the next pin
                    iPinNo++;
                    hr = pinEnum.Next(1, pins, ptrFetched);

                    // In case of error stop the pin enumeration
                    if (hr != 0)
                    {
                        break;
                    }

                    iFetched = Marshal.ReadInt32(ptrFetched);
                    if (iFetched == 1 && pins[0] != null)
                    {
                        PinInfo pinInfo;
                        hr = pins[0].QueryPinInfo(out pinInfo);
                        if (hr == 0)
                        {
                            ServiceRegistration.Get <ILogger>().Info("  got pin#{0}:{1}", iPinNo - 1, pinInfo.name);
                            FilterGraphTools.FreePinInfo(pinInfo);
                        }
                        else
                        {
                            ServiceRegistration.Get <ILogger>().Info("  got pin:?");
                        }
                        PinDirection pinDir;
                        pins[0].QueryDirection(out pinDir);
                        if (pinDir == PinDirection.Output)
                        {
                            IntPtr other_ptr;
                            hr = pins[0].ConnectedTo(out other_ptr);
                            if (hr == 0 && other_ptr != IntPtr.Zero)
                            {
                                ServiceRegistration.Get <ILogger>().Info("Reconnecting {0}:{1}", info.achName, pinInfo.name);
                                hr = graphBuilder.Reconnect(pins[0]);
                                if (hr != 0)
                                {
                                    ServiceRegistration.Get <ILogger>().Warn("Reconnect failed: {0}:{1}, code: 0x{2:x}", info.achName, pinInfo.name, hr);
                                }
                                IPin    other = Marshal.GetObjectForIUnknown(other_ptr) as IPin;
                                PinInfo otherPinInfo;
                                other.QueryPinInfo(out otherPinInfo);
                                ReConnectAll(graphBuilder, otherPinInfo.filter);
                                FilterGraphTools.FreePinInfo(otherPinInfo);
                                Marshal.ReleaseComObject(other);
                            }
                        }
                        Marshal.ReleaseComObject(pins[0]);
                    }
                    else
                    {
                        ServiceRegistration.Get <ILogger>().Info("no pins?");
                        break;
                    }
                }while (iFetched == 1);
                FilterGraphTools.TryRelease(ref pinEnum);
                Marshal.FreeCoTaskMem(ptrFetched);
            }
        }