/// <summary>
        /// Create or remove DSFilterNodes and Noodles based on state of FilterGraph
        /// </summary>
        public List <DSFilterNode> SyncGraphs(IBaseFilter manuallyAddedFilter)
        {
            List <DSFilterNode> nodesAdded = new List <DSFilterNode>();

            this.SuspendLayout();
            this.BeginNoodleUpdate();
            this.BeginCanvasUpdate();

            List <IBaseFilter>   filters = GetFilters(_Graph);
            List <IDaggerUINode> nodes   = AllNodes;

            // remove any nodes that no longer have corresponding IBaseFilters in the filtergraph
            foreach (DSFilterNodeUI node in nodes)
            {
                if (!filters.Contains((node.Node as DSFilterNode)._filter))
                {
                    this.Graph.DeleteNode(node.Node);
                }
            }

            // sync the pins in the nodes of the graph
            foreach (DaggerUINode node in AllNodes)
            {
                (node.Node as DSFilterNode).SyncPins();
            }

            // add nodes for any filters that aren't already in the graph
            for (int i = filters.Count - 1; i > -1; i--)
            {
                IBaseFilter filter = filters[i];

                // see if we haven't made a DaggerNode for this filter yet
                if (FindFilter(filter) == null)
                {
                    DSFilterNode node = new DSFilterNode(filter, manuallyAddedFilter == filter);
                    nodesAdded.Add(node);

                    // Setting _droppedNode to a value will make the node NOT visible when it's created.
                    // This way, we can reposition and resize the UINode before we display it.
                    _droppedNode = node;
                    Graph.AddNode(node);
                    _droppedNode = null;

                    // set the node's position and increment the drop location to the left
                    (node.UINode as DaggerUINode).Location = _dropLocation;
                    _dropLocation = new Point((node.UINode as DaggerUINode).Right + 24, _dropLocation.Y);
                    if (_dropLocation.X >= ActualCanvasSize.Width)
                    {
                        _dropLocation.X = 0;
                        _dropLocation.Y = _dropLocation.Y + (node.UINode as DaggerUINode).Height;
                    }

                    // mark the node visible
                    (node.UINode as DaggerUINode).Visible = true;
                }
                else
                {
                    // we already have a node for this one, release the ref enum.next added
                    if (filter.GetType().IsCOMObject)
                    {
                        int refc = Marshal.ReleaseComObject(filter);
                    }
                }
            }

            // purge disconnected noodles
            PurgeNoodles();

            // create new noodles
            BuildNoodles();

            // redraw the Canvas Image
            ResumeLayout();
            EndNoodleUpdate();
            EndCanvasUpdate();

            // route any dvd controls to thier video windows
            RouteDVDControl();

            // return the list of DSFilterNode that were added to the graph
            return(nodesAdded);
        }
示例#2
0
        /// <summary>
        /// Event that is raised after a DaggerNode has been created and associated to the UI element
        /// </summary>
        /// <param name="node"></param>
        void DSFilterNodeUI_DaggerNodeAttached(DaggerLib.Core.DaggerNode node)
        {
            _dsfilternode = (DSFilterNode)node;
            CaptionText   = node.ToString();

            // hook the AfterNodeRemoved event to dispose of any directshow interfaces
            node.AfterNodeRemoved += new DaggerLib.Core.AfterNodeRemoveHandler(node_AfterNodeRemoved);

            // get the IBaseFilter from the DSFilterNode
            IBaseFilter filter = _dsfilternode._filter;

            // only grab the video window or EVR if it was manually added to the graph via the UI
            if (_dsfilternode._manualAdded || (_dsfilternode.ParentGraph.ParentUIGraph as DSDaggerUIGraph)._filterGraphCreated)
            {
                // if it supports IVideoWindow create a VideoInternalWindow for it
                IVideoWindow vw = filter as IVideoWindow;
                if (vw != null)
                {
                    try
                    {
                        _videoWindow         = new VideoInternalWindow(CaptionText, filter);
                        _videoWindow.Dock    = DockStyle.Fill;
                        _videoWindow.Visible = true;
                        InternalControl.Controls.Add(_videoWindow);

                        // only nodes with video windows are resizeable
                        Resizable = true;

                        // hook the connection events to init/deinit the video window
                        node.ParentGraph.AfterPinsConnected += new DaggerLib.Core.PinAfterConnectedHandler(ParentGraph_AfterPinsConnected);
                    }
                    catch (Exception ex)
                    {
#if DEBUG
                        MessageBox.Show(ex.Message);
#endif
                        _videoWindow = null;
                    }
                }

                // if it's an Enhaced Video Renderer create a VideoInternalWindow for it
                // (see docs for Windows Media Foundation)
                IMFGetService mfgs = filter as IMFGetService;
                if (mfgs != null)
                {
                    // this is a video horse of a different color
                    // create a video clipping window for the Media Foundation Enhanced Video Renderer
                    try
                    {
                        // get the IMFVideoDisplayControl for the EVR filter
                        object o = null;
                        mfgs.GetService(MediaFoundation.MFServices.MR_VIDEO_RENDER_SERVICE,
                                        typeof(IMFVideoDisplayControl).GUID,
                                        out o
                                        );
                        m_pVideoDisplay = o as IMFVideoDisplayControl;

                        // if the Video Size is 0,0 the EVR hasn't been initialized/connected yet
                        MediaFoundation.Misc.SIZE videoSize = new MediaFoundation.Misc.SIZE();
                        MediaFoundation.Misc.SIZE ar        = new MediaFoundation.Misc.SIZE();
                        m_pVideoDisplay.GetNativeVideoSize(videoSize, ar);

                        if (videoSize.cx == 0 && videoSize.cy == 0)
                        {
                            // You only get one chance to set the number of pins in an EVR filter.
                            PinsComboBoxForm pcf = new PinsComboBoxForm();
                            if (pcf.ShowDialog() == DialogResult.OK)
                            {
                                (filter as IEVRFilterConfig).SetNumberOfStreams(pcf.Value);
                            }
                            pcf.Dispose();
                        }

                        _videoWindow         = new VideoInternalWindow(CaptionText, m_pVideoDisplay);
                        _videoWindow.Dock    = DockStyle.Fill;
                        _videoWindow.Visible = true;
                        InternalControl.Controls.Add(_videoWindow);

                        // only nodes with video windows are resizeable
                        Resizable = true;

                        // hook the connection events to init/deinit the video window
                        node.ParentGraph.AfterPinsConnected += new DaggerLib.Core.PinAfterConnectedHandler(ParentGraph_AfterPinsConnected);
                    }
                    catch (InvalidCastException)
                    {
                        m_pVideoDisplay = null;
                    }
                }
            }

            // if it's a DMO, create the DMO properties page for it
            if ((filter as IDMOWrapperFilter) != null)
            {
                // set the caption to show it's a DMO
                CaptionText           = "DMO - " + CaptionText;
                CaptionColor          = Color.Green;
                CaptionColorUnfocused = Color.LightGreen;
            }

            // remove clock button if it doesn't support IReferenceClock
            _referenceClock = filter as IReferenceClock;
            if (_referenceClock == null)
            {
                CaptionButtons.RemoveAt(CaptionButtons.AllButtons.IndexOf(_clockButton));
            }
            else
            {
                // see if this filter is the reference clock for the graph
                IReferenceClock graphClock = null;
                filter.GetSyncSource(out graphClock);
                _clockButton.Tag = false;
                _clockButton.MouseOutsideTint = Color.DarkGray;
                if (graphClock != null)
                {
                    if (graphClock == _referenceClock)
                    {
                        _clockButton.MouseOutsideTint = Color.Yellow;
                        _clockButton.Tag = true;
                    }
                    Marshal.ReleaseComObject(graphClock);
                }
            }

            // remove video window button if it's not a video window
            if (_videoWindow == null)
            {
                CaptionButtons.RemoveAt(CaptionButtons.AllButtons.IndexOf(_detachVideoWindowButton));
            }

            // Sync the pins to the Pin Property Pages
            SyncPinPropertyPages(null);

            // set it to the smallest possible size.  DaggerLib uses InternalControlMinimumSize
            // to prevent the UI node from being smaller than designated
            this.Size = new Size(1, 1);
        }