From 2e73a77538f261fb5174f62c1f9842f1a59cf2ac Mon Sep 17 00:00:00 2001 From: Jordan Wages Date: Tue, 3 Jul 2018 18:59:28 -0500 Subject: [PATCH] Advanced options and documentation Added a lot of new advanced options and documented a lot of functions and members. --- butterflow-ui/ButterflowOption.cs | 1 + butterflow-ui/ButterflowSubregion.cs | 3 +- butterflow-ui/ButterflowWrapper.cs | 121 ++++++++++-- butterflow-ui/Icons.xaml | 18 ++ .../Localization/Localization.Designer.cs | 148 ++++++++++++++- butterflow-ui/Localization/Localization.resx | 52 ++++- butterflow-ui/MainWindow.xaml | 54 +++++- butterflow-ui/MainWindow.xaml.cs | 25 ++- butterflow-ui/OptionsConfiguration.cs | 178 +++++++++++++++++- butterflow-ui/PropertyChangedAlerter.cs | 1 + 10 files changed, 568 insertions(+), 33 deletions(-) diff --git a/butterflow-ui/ButterflowOption.cs b/butterflow-ui/ButterflowOption.cs index 0025f6b..8ceccd9 100644 --- a/butterflow-ui/ButterflowOption.cs +++ b/butterflow-ui/ButterflowOption.cs @@ -8,6 +8,7 @@ using System.Windows.Controls; namespace butterflow_ui { + /// A butterflowUI option. Contains layout information for use in butterflowUI. public class ButterflowOption : ContentControl { #region Properties diff --git a/butterflow-ui/ButterflowSubregion.cs b/butterflow-ui/ButterflowSubregion.cs index 9a57a66..1f7c20a 100644 --- a/butterflow-ui/ButterflowSubregion.cs +++ b/butterflow-ui/ButterflowSubregion.cs @@ -6,7 +6,8 @@ using System.Threading.Tasks; namespace butterflow_ui { - public class ButterflowSubregion : PropertyChangedAlerter, System.ComponentModel.INotifyPropertyChanged + /// A butterflow video subregion. Represents a snippet of a video on which butterflow will act. + public class ButterflowSubregion : PropertyChangedAlerter { #region Members diff --git a/butterflow-ui/ButterflowWrapper.cs b/butterflow-ui/ButterflowWrapper.cs index d25cf30..41f50d5 100644 --- a/butterflow-ui/ButterflowWrapper.cs +++ b/butterflow-ui/ButterflowWrapper.cs @@ -5,20 +5,27 @@ using System.IO; using System.Linq; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace butterflow_ui { + /// A butterflow wrapper. Provides interaction with the butterflow executable. public class ButterflowWrapper : PropertyChangedAlerter { #region Members + /// The RegEx string for matching probed resolution. + private const string REGEX_RESOLUTION = @"Resolution\s*:\s(?\d+)x(?\d+)"; + /// The RegEx string for matching the probed playback rate.. + private const string REGEX_RATE = @"Rate\s*:\s(?\d+\.\d+) fps"; + /// Full pathname of the butterflow executable file. private Lazy executablePath = new Lazy(() => Path.Combine(Directory.GetCurrentDirectory(), "ThirdPartyCompiled", "butterflow.exe")); /// The console output from butterflow. private string consoleOutput = string.Empty; - /// Event queue for all listeners interested in ConsoleOutputRecieved events. - //public event EventHandler ConsoleOutputRecieved; + /// Event queue for all listeners interested in ParsedConsoleOutputRecieved events. + public event EventHandler ParsedConsoleOutputRecieved; #endregion @@ -71,35 +78,100 @@ namespace butterflow_ui process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.EnableRaisingEvents = true; - process.OutputDataReceived += ProcessOutputDataReceived; + process.OutputDataReceived += Process_OutputDataReceived; ; process.Start(); process.BeginOutputReadLine(); } - /// Process the output data received from the butterflow executable. - /// Source of the event. - /// Data received event information. - private void ProcessOutputDataReceived(object sender, DataReceivedEventArgs e) + /// + /// Parses console output and attempts to find known values. If a known value is found, the + /// event is triggered. + /// + /// The console output from butterflow. + private void ParseConsoleOutput(string consoleOutput) { - this.ConsoleOutput += string.Format("{0}{1}", e.Data, Environment.NewLine); - //OnConsoleOutputRecieved(e.Data); + if (string.IsNullOrWhiteSpace(consoleOutput)) + { + //Ignore null content and just escape. + return; + } + + //Test for resolution + var regex = new Regex(REGEX_RESOLUTION); + foreach (Match match in regex.Matches(consoleOutput)) + { + var width = match.Groups["Width"].Value; + var height = match.Groups["Height"].Value; + + OnParsedConsoleOutputRecieved(ButterflowOutputType.Width, width, consoleOutput); + OnParsedConsoleOutputRecieved(ButterflowOutputType.Height, height, consoleOutput); + } + + //Test for playback rate + regex = new Regex(REGEX_RATE); + foreach(Match match in regex.Matches(consoleOutput)) + { + var rate = match.Groups["Rate"].Value; + + OnParsedConsoleOutputRecieved(ButterflowOutputType.Rate, rate, consoleOutput); + } } - /// Executes the console output recieved event handler. - /// The output that has been recieved from butterflow. - //protected void OnConsoleOutputRecieved(string output) - //{ - // if (this.ConsoleOutputRecieved != null) - // { - // this.ConsoleOutputRecieved(this, new ButterflowConsoleOutputArgs(output)); - // } - //} + /// Executes the parsed console output recieved action. + /// Type of the output. + /// The value. + /// The console output from butterflow. + private void OnParsedConsoleOutputRecieved(ButterflowOutputType outputType, string value, string consoleOutput) + { + if (this.ParsedConsoleOutputRecieved != null) + { + this.ParsedConsoleOutputRecieved(this, new ButterflowOutputArgs(outputType, value, consoleOutput)); + } + } + + /// Event handler. Called by Process for output data received events. + /// Source of the event. + /// Data received event information. + private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e) + { + this.ConsoleOutput += string.Format("{0}{1}", e.Data, Environment.NewLine); + ParseConsoleOutput(e.Data); + } #endregion #region Subclasses + /// Arguments for butterflow output events where a known value of type can be parsed. + public class ButterflowOutputArgs : ButterflowConsoleOutputArgs + { + + #region Properties + + /// Gets or sets the type of the output detected from butterflow. + /// The type of the output detected from butterflow. + public ButterflowOutputType OutputType { get; private set; } + + /// Gets or sets the value detected from butterflow. + /// The value detected from butterflow. + public string Value { get; private set; } + + #endregion + + /// Constructor. + /// The type of the output detected from butterflow. + /// The value detected from butterflow. + /// The console output. + public ButterflowOutputArgs(ButterflowOutputType outputType, string value, string consoleOutput) + : base(consoleOutput) + { + this.OutputType = outputType; + this.Value = value; + } + } + + /// Arguments for butterflow console output events. public class ButterflowConsoleOutputArgs : EventArgs { #region Properties @@ -122,6 +194,19 @@ namespace butterflow_ui #endregion } + /// Values that represent butterflow output types. + public enum ButterflowOutputType + { + /// Video Width. + Width, + /// Video Height. + Height, + /// Video playback rate. + Rate, + /// Video processing progress. + Progress + } + #endregion } } diff --git a/butterflow-ui/Icons.xaml b/butterflow-ui/Icons.xaml index cbd5c96..1118b6a 100644 --- a/butterflow-ui/Icons.xaml +++ b/butterflow-ui/Icons.xaml @@ -130,4 +130,22 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/butterflow-ui/Localization/Localization.Designer.cs b/butterflow-ui/Localization/Localization.Designer.cs index a515681..db8c665 100644 --- a/butterflow-ui/Localization/Localization.Designer.cs +++ b/butterflow-ui/Localization/Localization.Designer.cs @@ -124,7 +124,7 @@ namespace butterflow_ui.Localization { } /// - /// Looks up a localized string similar to More about butterflow.... + /// Looks up a localized string similar to butterflow on github.... /// public static string AboutButterflowMenu { get { @@ -133,7 +133,7 @@ namespace butterflow_ui.Localization { } /// - /// Looks up a localized string similar to More about butterflow-ui.... + /// Looks up a localized string similar to butterflow-ui on github.... /// public static string AboutButterflowUIMenu { get { @@ -204,6 +204,24 @@ namespace butterflow_ui.Localization { } } + /// + /// Looks up a localized string similar to Use Fast Pyramids. + /// + public static string FastPyramidsLabel { + get { + return ResourceManager.GetString("FastPyramidsLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to . + /// + public static string FastPyramidsTooltip { + get { + return ResourceManager.GetString("FastPyramidsTooltip", resourceCulture); + } + } + /// /// Looks up a localized string similar to Input. /// @@ -249,6 +267,24 @@ namespace butterflow_ui.Localization { } } + /// + /// Looks up a localized string similar to Pyramid iterations. + /// + public static string IterationsLabel { + get { + return ResourceManager.GetString("IterationsLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The number of iterations to use for each pyramid layer.. + /// + public static string IterationsTooltip { + get { + return ResourceManager.GetString("IterationsTooltip", resourceCulture); + } + } + /// /// Looks up a localized string similar to Renders the output video with the audio from the original video. In unchecked, no sound will be included in the output video.. /// @@ -267,6 +303,24 @@ namespace butterflow_ui.Localization { } } + /// + /// Looks up a localized string similar to Levels. + /// + public static string LevelsLabel { + get { + return ResourceManager.GetString("LevelsLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The number of pyramid layers.. + /// + public static string LevelsTooltip { + get { + return ResourceManager.GetString("LevelsTooltip", resourceCulture); + } + } + /// /// Looks up a localized string similar to Renders the video without lossy compression. The video will not lose any visual quality, but it will result in a very large output file.. /// @@ -285,6 +339,24 @@ namespace butterflow_ui.Localization { } } + /// + /// Looks up a localized string similar to Pixel Neighborhood. + /// + public static string PixelNeighborhoodLabel { + get { + return ResourceManager.GetString("PixelNeighborhoodLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Size of the pixel neighborhood.. + /// + public static string PixelNeighborhoodTooltip { + get { + return ResourceManager.GetString("PixelNeighborhoodTooltip", resourceCulture); + } + } + /// /// Looks up a localized string similar to Controls the new framerate of the output video. This can be set in both absolute and relative terms.. /// @@ -312,6 +384,24 @@ namespace butterflow_ui.Localization { } } + /// + /// Looks up a localized string similar to Pyramid Scale Factor. + /// + public static string PyramidScaleLabel { + get { + return ResourceManager.GetString("PyramidScaleLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to . + /// + public static string PyramidScaleTooltip { + get { + return ResourceManager.GetString("PyramidScaleTooltip", resourceCulture); + } + } + /// /// Looks up a localized string similar to Video Rendering. /// @@ -348,6 +438,42 @@ namespace butterflow_ui.Localization { } } + /// + /// Looks up a localized string similar to Smooth Derivative. + /// + public static string SmoothDerivativeLabel { + get { + return ResourceManager.GetString("SmoothDerivativeLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Size of the standard deviation used for smooth derivatives.. + /// + public static string SmoothDerivativeTooltip { + get { + return ResourceManager.GetString("SmoothDerivativeTooltip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Smooth Motion. + /// + public static string SmoothMotionLabel { + get { + return ResourceManager.GetString("SmoothMotionLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set to tune for smooth motion. This mode yields artifact-less frames by emphasizing blended frames over warping pixels.. + /// + public static string SmoothMotionTooltip { + get { + return ResourceManager.GetString("SmoothMotionTooltip", resourceCulture); + } + } + /// /// Looks up a localized string similar to S. /// @@ -410,5 +536,23 @@ namespace butterflow_ui.Localization { return ResourceManager.GetString("WidthLabel", resourceCulture); } } + + /// + /// Looks up a localized string similar to Window Size. + /// + public static string WindowSizeLabel { + get { + return ResourceManager.GetString("WindowSizeLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to . + /// + public static string WindowSizeTooltip { + get { + return ResourceManager.GetString("WindowSizeTooltip", resourceCulture); + } + } } } diff --git a/butterflow-ui/Localization/Localization.resx b/butterflow-ui/Localization/Localization.resx index 0aefc13..ebf53cf 100644 --- a/butterflow-ui/Localization/Localization.resx +++ b/butterflow-ui/Localization/Localization.resx @@ -118,10 +118,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - More about butterflow... + butterflow on github... - More about butterflow-ui... + butterflow-ui on github... About butterflow-ui @@ -234,4 +234,52 @@ 60 fps + + Use Fast Pyramids + + + + + + Pyramid iterations + + + The number of iterations to use for each pyramid layer. + + + Levels + + + The number of pyramid layers. + + + Pixel Neighborhood + + + Size of the pixel neighborhood. + + + Pyramid Scale Factor + + + + + + Smooth Derivative + + + Size of the standard deviation used for smooth derivatives. + + + Smooth Motion + + + Set to tune for smooth motion. This mode yields artifact-less frames by emphasizing blended frames over warping pixels. + + + Window Size + + + + \ No newline at end of file diff --git a/butterflow-ui/MainWindow.xaml b/butterflow-ui/MainWindow.xaml index aaa9bd5..0338a63 100644 --- a/butterflow-ui/MainWindow.xaml +++ b/butterflow-ui/MainWindow.xaml @@ -127,13 +127,37 @@ + - + - - + + + + + + + + @@ -161,6 +185,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/butterflow-ui/MainWindow.xaml.cs b/butterflow-ui/MainWindow.xaml.cs index 2f77bf1..c53b523 100644 --- a/butterflow-ui/MainWindow.xaml.cs +++ b/butterflow-ui/MainWindow.xaml.cs @@ -43,9 +43,30 @@ namespace butterflow_ui /// Default constructor. public MainWindow() { + this.ButterflowWrapper.ParsedConsoleOutputRecieved += ButterflowWrapper_ParsedConsoleOutputRecieved; InitializeComponent(); } + /// Butterflow wrapper parsed console output recieved. + /// Source of the event. + /// The ButterflowOutputArgs to process. + private void ButterflowWrapper_ParsedConsoleOutputRecieved(object sender, ButterflowWrapper.ButterflowOutputArgs e) + { + switch (e.OutputType) + { + case ButterflowWrapper.ButterflowOutputType.Width: + this.OptionsConfiguration.Width = e.Value; + break; + case ButterflowWrapper.ButterflowOutputType.Height: + this.OptionsConfiguration.Height = e.Value; + break; + case ButterflowWrapper.ButterflowOutputType.Progress: + break; + default: + break; + } + } + /// Event handler. Called by btnFilePicker for click events. /// Source of the event. /// Routed event information. @@ -164,8 +185,8 @@ namespace butterflow_ui /// Routed event information. private void mediaPreview_MediaOpened(object sender, RoutedEventArgs e) { - this.OptionsConfiguration.Width = this.mediaPreview.NaturalVideoWidth.ToString(); - this.OptionsConfiguration.Height = this.mediaPreview.NaturalVideoHeight.ToString(); + //this.OptionsConfiguration.Width = this.mediaPreview.NaturalVideoWidth.ToString(); + //this.OptionsConfiguration.Height = this.mediaPreview.NaturalVideoHeight.ToString(); } /// Event handler. Called by mediaPreview for media ended events. diff --git a/butterflow-ui/OptionsConfiguration.cs b/butterflow-ui/OptionsConfiguration.cs index f2bca59..4932c43 100644 --- a/butterflow-ui/OptionsConfiguration.cs +++ b/butterflow-ui/OptionsConfiguration.cs @@ -10,7 +10,7 @@ using csmic; namespace butterflow_ui { - /// (Serializable) the options configuration. + /// The butterflow options configuration. Contians all the options necessary to run butterflow and process a video. [Serializable] public class OptionsConfiguration : PropertyChangedAlerter { @@ -18,6 +18,8 @@ namespace butterflow_ui /// An interpreter used to ensure numeric input is correctly calculated. private InputInterpreter interpreter = new InputInterpreter(); + /// The aspect ratio used for calculating heights when the aspect ratio is locked. + private decimal aspectRatio = 0; private string playbackRate; private bool keepAudio; @@ -25,8 +27,17 @@ namespace butterflow_ui private int height; private bool keepAspectRatio; private bool losslessQuality; + private bool smoothMotion; + private bool lockAspectRatio; private string videoInput; private string videoOutput; + private bool fastPyramid; + private decimal pyramidScale; + private int levels; + private int windowSize; + private int iterations; + private int pixelNeighborhood; + private decimal smoothDerivativeStandardDeviation; private ObservableCollection subregions = new ObservableCollection(); #endregion @@ -73,6 +84,41 @@ namespace butterflow_ui } } + /// Gets or sets a value indicating whether the butterflow should be turned toward smooth motion. + /// True if tuned toward smooth motion, false if not. + public bool SmoothMotion + { + get + { + return this.smoothMotion; + } + set + { + this.smoothMotion = value; + OnPropertyChanged(); + } + } + + /// Gets or sets a value indicating whether to lock aspect ratio of the video. + /// True if locking aspect ratio of the video, false if not. + public bool LockAspectRatio + { + get + { + return this.lockAspectRatio; + } + set + { + if (value) + { + this.aspectRatio = Convert.ToDecimal(this.height) / Convert.ToDecimal(this.width); + } + + this.lockAspectRatio = value; + OnPropertyChanged(); + } + } + /// Gets or sets the width of the video output. /// The width of the video output. public string Width @@ -83,9 +129,20 @@ namespace butterflow_ui } set { + var oldWidth = this.width; + interpreter.Interpret(value); this.width = interpreter.Int; + OnPropertyChanged(); + + if (this.lockAspectRatio) + { + interpreter.Interpret(string.Format("{0} * {1}", this.aspectRatio, this.width)); + this.height = interpreter.Int; + + OnPropertyChanged("Height"); + } } } @@ -165,6 +222,117 @@ namespace butterflow_ui } } + /// Gets or sets a value indicating whether to use fast pyramids. + /// True if using fast pyramids, false if not. + public bool FastPyramid + { + get + { + return this.fastPyramid; + } + set + { + this.fastPyramid = value; + OnPropertyChanged(); + } + } + + /// Gets or sets the pyramid scale factor. + /// The pyramid scale factor. + public string PyramidScale + { + get + { + return this.pyramidScale.ToString(); + } + set + { + interpreter.Interpret(value); + this.pyramidScale = interpreter.Decimal; + OnPropertyChanged(); + } + } + + /// Gets or sets the number of pyramid layers. + /// The number of pyramid layers. + public string Levels + { + get + { + return this.levels.ToString(); + } + set + { + interpreter.Interpret(value); + this.levels = interpreter.Int; + OnPropertyChanged(); + } + } + + /// Gets or sets the size of the windowing average. + /// The size of the windowing average. + public string WindowSize + { + get + { + return this.windowSize.ToString(); + } + set + { + interpreter.Interpret(value); + this.windowSize = interpreter.Int; + OnPropertyChanged(); + } + } + + /// Gets or sets the number of iterations at each pyramid level. + /// The number of iterations at each pyramid level. + public string Iterations + { + get + { + return this.iterations.ToString(); + } + set + { + interpreter.Interpret(value); + this.iterations = interpreter.Int; + OnPropertyChanged(); + } + } + + /// Gets or sets the size of the pixel neighborhood. + /// The size of the pixel neighborhood. + public string PixelNeighborhood + { + get + { + return this.pixelNeighborhood.ToString(); + } + set + { + interpreter.Interpret(value); + this.pixelNeighborhood = interpreter.Int; + OnPropertyChanged(); + } + } + + /// Gets or sets the standard deviation of smooth derivatives. + /// The standard deviation of smooth derivatives. + public string SmoothDerivativeStandardDeviation + { + get + { + return this.smoothDerivativeStandardDeviation.ToString(); + } + set + { + interpreter.Interpret(value); + this.smoothDerivativeStandardDeviation = interpreter.Decimal; + OnPropertyChanged(); + } + } + /// Gets or sets the subregions of the video on which to work. /// The subregions of the video. public ObservableCollection Subregions @@ -194,16 +362,16 @@ namespace butterflow_ui private void SubregionsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { - if(e.NewItems != null) + if (e.NewItems != null) { - foreach(ButterflowSubregion newItem in e.NewItems) + foreach (ButterflowSubregion newItem in e.NewItems) { newItem.PropertyChanged += SubregionPropertyChanged; } } - if(e.OldItems != null) + if (e.OldItems != null) { - foreach(ButterflowSubregion oldItem in e.OldItems) + foreach (ButterflowSubregion oldItem in e.OldItems) { oldItem.PropertyChanged -= SubregionPropertyChanged; } diff --git a/butterflow-ui/PropertyChangedAlerter.cs b/butterflow-ui/PropertyChangedAlerter.cs index 0b90ba9..6fd36a9 100644 --- a/butterflow-ui/PropertyChangedAlerter.cs +++ b/butterflow-ui/PropertyChangedAlerter.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; namespace butterflow_ui { + /// A class responsible for implementing the interface and helper functions. public abstract class PropertyChangedAlerter : INotifyPropertyChanged { #region Members