Ejemplo n.º 1
0
        /// <summary>
        /// Sucht eine Konfiguration der Teildatenströme, die eine Aufzeichnung aller Quellen
        /// eventuell mit Reduktion des Aufzeichnungsumfangs erlaubt.
        /// </summary>
        /// <param name="disableOrder">Die Liste der Aspekte, die ausgeblendet werden dürfen.</param>
        /// <returns>Die Anzahl der Quellen, die verwendet werden können.</returns>
        public int Optimize(params StreamDisableSelector[] disableOrder)
        {
            // No souces
            if (m_Sources.Count < 1)
            {
                return(m_Sources.Count);
            }

            // Total stream count
            int available;

            // No limit
            using (HardwareManager.Open())
            {
                // Attach to the device
                Hardware device = m_Sources[0].Source.GetHardware();

                // No limit at all
                if (!device.HasConsumerRestriction)
                {
                    return(m_Sources.Count);
                }

                // Get all the active streams
                ushort[] activeStreams = device.GetActiveStreams();

                // Ask for it
                available = device.Restrictions.ConsumerLimit.Value - activeStreams.Length;

                // None at all
                if (available < 1)
                {
                    return(0);
                }

                // Stream managers in use
                List <SourceStreamsManager> managers = new List <SourceStreamsManager>();
                try
                {
                    // Create one by one
                    for (int i = 0; i < m_Sources.Count; ++i)
                    {
                        // Attach
                        SelectionInfo info = m_Sources[i];

                        // Create new manager
                        SourceStreamsManager manager = info.Source.Open(info.OriginalStreams);

                        // Remember for cleanupo
                        managers.Add(manager);

                        // See if source is available
                        if (!manager.CreateStream(null))
                        {
                            // Fake entry - will not be used
                            info.CurrentStreams = info.OriginalStreams.Clone();
                            info.ConsumerCount  = 0;
                        }
                        else
                        {
                            // Remember all we found
                            info.CurrentStreams = manager.ActiveSelection;
                            info.ConsumerCount  = manager.ConsumerCount;
                        }
                    }

                    // Whoo - can open it all as requested
                    return(m_Sources.Count);
                }
                catch (OutOfConsumersException)
                {
                }
                finally
                {
                    // Terminate all
                    foreach (SourceStreamsManager manager in managers)
                    {
                        manager.Dispose();
                    }
                }

                // First try to make sure that each source can be opened in stand-alone mode
                foreach (SelectionInfo info in m_Sources)
                {
                    info.Optimize(disableOrder, Report);
                }

                // Now simulate starting all - will try to get most out of the first one and so on
                for (int ixStream = 0; ixStream < m_Sources.Count; ixStream++)
                {
                    // Attach to the item
                    SelectionInfo current = m_Sources[ixStream];

                    // See how many additional streams will be needed
                    int needed = current.ConsumerCount.Value - available;

                    // Try to free some
                    for (int ixDisable = 0; (needed > 0) && (ixDisable < disableOrder.Length);)
                    {
                        // Load the next option
                        StreamDisableSelector disable = disableOrder[ixDisable++];

                        // Apply self
                        current.ApplyDisable(disable, StreamDisableMode.Self, ref needed, Report);

                        // Apply higher priorized
                        for (int ixHigher = ixStream; (needed > 0) && (ixHigher-- > 0);)
                        {
                            m_Sources[ixHigher].ApplyDisable(disable, StreamDisableMode.Higher, ref needed, Report);
                        }
                    }

                    // Should not be startet - we find no way to provide a proper subset of streams
                    if (needed > 0)
                    {
                        return(ixStream);
                    }

                    // Back to what is left
                    available = -needed;
                }

                // Not possible
                return(m_Sources.Count);
            }
        }