Example #1
0
        /// <summary>
        /// Finds the shortest mux path for a given set of input MuxableTypes (ie the
        /// encoder output types have all already been chosen here).
        /// </summary>
        /// Initial stage: if currentMuxPath is empty, it creates a first leg.
        /// Recursive step: It tries out adding all possible muxers to the current mux path,
        ///                 and calls itself with this extended mux path. It returns the shortest path.
        /// Final step: This will stop recursing if there are no muxers that can help, or if a muxer
        ///                 is found in one step that finalizes the path. This is guaranteed to finish:
        ///                 if no progress is made, then it will not recurse. Otherwise, there is a finite
        ///                 amount of progress (progress is the number of streams muxed), so it will eventually
        ///                 stop progressing.
        /// <param name="currentMuxPath">Current mux path to be worked on</param>
        /// <param name="unhandledDesiredInputTypes">What remains to be muxed</param>
        /// <param name="desiredContainerType">Container type we are aiming at</param>
        /// <returns></returns>
        private MuxPath getShortestMuxPath(MuxPath currentMuxPath,
                                           List <MuxableType> unhandledDesiredInputTypes, ContainerType desiredContainerType)
        {
            if (currentMuxPath.IsCompleted())
            {
                return(currentMuxPath);
            }


            List <MuxableType> handledInputTypes;
            List <MuxableType> unhandledInputTypes;
            List <MuxPath>     allMuxPaths = new List <MuxPath>();

            foreach (IMuxing muxer in mainForm.PackageSystem.MuxerProviders.Values)
            {
                ProcessingLevel level;
                if (currentMuxPath.Length > 0)
                {
                    level = muxer.CanBeProcessed(
                        currentMuxPath[currentMuxPath.Length - 1].muxerInterface.GetSupportedContainerTypes().ToArray(),
                        unhandledDesiredInputTypes.ToArray(), out handledInputTypes, out unhandledInputTypes);
                }
                else
                {
                    level = muxer.CanBeProcessed(unhandledDesiredInputTypes.ToArray(), out handledInputTypes, out unhandledInputTypes);
                }
                if (level != ProcessingLevel.NONE)
                {
                    MuxPath newMuxPath = currentMuxPath.Clone();

                    MuxPathLeg currentMPL = new MuxPathLeg();
                    currentMPL.muxerInterface      = muxer;
                    currentMPL.handledInputTypes   = handledInputTypes;
                    currentMPL.unhandledInputTypes = unhandledInputTypes;
                    newMuxPath.Add(currentMPL);

                    if (unhandledInputTypes.Count == 0)
                    {
                        // All the streams have been muxed into some file. Now let's
                        // just make sure that we can convert this file to the format we want
                        // (or leave it alone if it already is in that format).
                        List <IMuxing> allMuxers = new List <IMuxing>();
                        allMuxers.AddRange(mainForm.PackageSystem.MuxerProviders.Values);
                        MuxPath shortestPath = getShortestMuxPath(newMuxPath, allMuxers, desiredContainerType);
                        if (shortestPath != null)
                        {
                            allMuxPaths.Add(shortestPath);
                        }
                    }

                    MuxPath aShortestPath = getShortestMuxPath(currentMuxPath, muxer, new List <MuxableType>(), handledInputTypes, unhandledInputTypes, desiredContainerType);
                    if (aShortestPath != null)
                    {
                        allMuxPaths.Add(aShortestPath);
                    }
                }
            }
            return(comparer.GetBestMuxPath(allMuxPaths));
        }
Example #2
0
        /// <summary>
        /// Recurses to find the shortest mux path.
        /// </summary>
        /// Initial stage: if currentMuxPath is empty, it creates a first leg.
        /// Recursive step: It tries out adding all possible muxers to the current mux path,
        ///                 and calls itself with this extended mux path. It returns the shortest path.
        /// Final step: This will stop recursing if there are no muxers that can help, or if a muxer
        ///                 is found in one step that finalizes the path. This is guaranteed to finish:
        ///                 if no progress is made, then it will not recurse. Otherwise, there is a finite
        ///                 amount of progress (progress is the number of streams muxed), so it will eventually
        ///                 stop progressing.
        /// <param name="currentMuxPath">Current mux path to be worked on</param>
        /// <param name="unhandledDesiredInputTypes">What remains to be muxed</param>
        /// <param name="desiredContainerType">Container type we are aiming at</param>
        /// <returns></returns>
        private MuxPath getShortestMuxPath(MuxPath currentMuxPath,
                                           List <MuxableType> unhandledDesiredInputTypes, ContainerType desiredContainerType)
        {
            List <MuxableType> handledInputTypes   = new List <MuxableType>();
            List <MuxableType> unhandledInputTypes = new List <MuxableType>();
            List <MuxPath>     allMuxPaths         = new List <MuxPath>();

            if (currentMuxPath.IsCompleted())
            {
                return(currentMuxPath);
            }

            foreach (IMuxing muxer in mainForm.PackageSystem.MuxerProviders.Values)
            {
                ProcessingLevel level;
                if (currentMuxPath.Length > 0)
                {
                    level = muxer.CanBeProcessed(
                        currentMuxPath[currentMuxPath.Length - 1].muxerInterface.GetSupportedContainerTypes().ToArray(),
                        unhandledDesiredInputTypes.ToArray(), out handledInputTypes, out unhandledInputTypes);
                }
                else
                {
                    level = muxer.CanBeProcessed(unhandledDesiredInputTypes.ToArray(), out handledInputTypes, out unhandledInputTypes);
                }
                if (level != ProcessingLevel.NONE)
                {
                    MuxPath newMuxPath = currentMuxPath.Clone();

                    MuxPathLeg currentMPL = new MuxPathLeg();
                    currentMPL.muxerInterface      = muxer;
                    currentMPL.handledInputTypes   = handledInputTypes;
                    currentMPL.unhandledInputTypes = unhandledInputTypes;
                    newMuxPath.Add(currentMPL);

                    if (unhandledInputTypes.Count == 0)
                    {
                        List <IMuxing> allMuxers = new List <IMuxing>();
                        allMuxers.AddRange(mainForm.PackageSystem.MuxerProviders.Values);
                        MuxPath shortestPath = getShortestMuxPath(newMuxPath, allMuxers, desiredContainerType);
                        if (shortestPath != null)
                        {
                            allMuxPaths.Add(shortestPath);
                        }
                    }

                    MuxPath aShortestPath = getShortestMuxPath(currentMuxPath, muxer, new List <MuxableType>(), handledInputTypes, unhandledInputTypes, desiredContainerType);
                    if (aShortestPath != null)
                    {
                        allMuxPaths.Add(aShortestPath);
                    }
                }
            }
            return(comparer.GetBestMuxPath(allMuxPaths));
        }
Example #3
0
        /// <summary>
        /// Step in the recursive stage which chooses, of all the MuxableTypes which
        /// *could* be handled, whether they should be. That means, it generates a
        /// mux path which involves muxing in each of the 2^n combinations of inputs
        /// at this stage.
        ///
        /// I'm not sure if this step is actually necessary. The only possible
        /// use I can think of is if you have a specific muxpath rule which says
        /// that only one file can be muxed in at a time, or only some specific
        /// combination of files can be muxed in at a time.
        ///           -- berrinam
        /// </summary>
        /// <param name="currentMuxPath"></param>
        /// <param name="muxer"></param>
        /// <param name="decidedHandledTypes"></param>
        /// <param name="undecidedPossibleHandledTypes"></param>
        /// <param name="unhandledInputTypes"></param>
        /// <param name="desiredContainerType"></param>
        /// <returns></returns>
        private MuxPath getShortestMuxPath(MuxPath currentMuxPath, IMuxing muxer, List <MuxableType> decidedHandledTypes,
                                           List <MuxableType> undecidedPossibleHandledTypes, List <MuxableType> unhandledInputTypes, ContainerType desiredContainerType)
        {
            if (undecidedPossibleHandledTypes.Count == 0)
            {
                MuxPathLeg mpl = new MuxPathLeg();
                mpl.muxerInterface      = muxer;
                mpl.handledInputTypes   = new List <MuxableType>(decidedHandledTypes);
                mpl.unhandledInputTypes = new List <MuxableType>(unhandledInputTypes);
                MuxPath newMuxPath = currentMuxPath.Clone();
                newMuxPath.Add(mpl);
                if (decidedHandledTypes.Count == 0)
                {
                    return(null);
                }
                return(getShortestMuxPath(newMuxPath, unhandledInputTypes, desiredContainerType));
            }
            else
            {
                List <MuxPath> allMuxPaths = new List <MuxPath>();
                MuxableType    type        = undecidedPossibleHandledTypes[0];
                undecidedPossibleHandledTypes.RemoveAt(0);

                decidedHandledTypes.Add(type);
                MuxPath shortestMuxPath = getShortestMuxPath(currentMuxPath, muxer, decidedHandledTypes, undecidedPossibleHandledTypes, unhandledInputTypes, desiredContainerType);
                if (shortestMuxPath != null)
                {
                    allMuxPaths.Add(shortestMuxPath);
                }
                decidedHandledTypes.Remove(type);

                unhandledInputTypes.Add(type);
                shortestMuxPath = getShortestMuxPath(currentMuxPath, muxer, decidedHandledTypes, undecidedPossibleHandledTypes, unhandledInputTypes, desiredContainerType);
                if (shortestMuxPath != null)
                {
                    allMuxPaths.Add(shortestMuxPath);
                }
                unhandledInputTypes.Remove(type);

                undecidedPossibleHandledTypes.Add(type);

                return(comparer.GetBestMuxPath(allMuxPaths));
            }
        }
Example #4
0
        /// <summary>
        /// Given a mux path in which all the inputs have already been handled,
        /// this finds the shortest mux path to achieve the desired container type.
        /// </summary>
        /// <param name="currentMuxPath"></param>
        /// <param name="remainingMuxers">List of muxers which haven't yet been used
        /// in this final stage. There's no point having a muxer twice in this final
        /// stage, as the output of the second time could substitute the output of
        /// the first time.</param>
        /// <param name="desiredContainerType"></param>
        /// <returns></returns>
        private MuxPath getShortestMuxPath(MuxPath currentMuxPath,
                                           List <IMuxing> remainingMuxers, ContainerType desiredContainerType)
        {
            if (currentMuxPath.IsCompleted())
            {
                return(currentMuxPath);
            }

            List <MuxPath> allMuxPaths = new List <MuxPath>();

            List <IMuxing> newRemainingMuxers = new List <IMuxing>();

            newRemainingMuxers.AddRange(remainingMuxers);

            foreach (IMuxing muxer in remainingMuxers)
            {
                bool supportsInput = currentMuxPath[currentMuxPath.Length - 1].muxerInterface.GetContainersInCommon(muxer).Count > 0;
                if (!supportsInput)
                {
                    continue;
                }

                MuxPath newMuxPath = currentMuxPath.Clone();

                MuxPathLeg currentMPL = new MuxPathLeg();
                currentMPL.muxerInterface      = muxer;
                currentMPL.handledInputTypes   = new List <MuxableType>();
                currentMPL.unhandledInputTypes = new List <MuxableType>();
                newMuxPath.Add(currentMPL);

                newRemainingMuxers.Remove(muxer);
                MuxPath shortestPath = getShortestMuxPath(newMuxPath, newRemainingMuxers, desiredContainerType);
                if (shortestPath != null)
                {
                    allMuxPaths.Add(shortestPath);
                }
                newRemainingMuxers.Add(muxer);
            }
            return(comparer.GetBestMuxPath(allMuxPaths));
        }
Example #5
0
 public void Add(MuxPathLeg leg)
 {
     path.Add(leg);
 }