From e703a7961f12a3e02c475754862a1f4a57a04646 Mon Sep 17 00:00:00 2001 From: Scott Date: Sat, 26 Sep 2015 20:58:05 +0100 Subject: AppServices tidyup Moving the UI modelling and services to the GUI Project. --- .../Converters/Audio/AudioEncoderConverter.cs | 7 +- .../Converters/Audio/AudioQueueDisplayConverter.cs | 6 +- .../Converters/Audio/AudioRateTypeConverter.cs | 3 +- .../HandBrakeWPF/Converters/EnumComboConverter.cs | 2 +- .../Converters/Filters/DenoisePresetConverter.cs | 3 +- .../Subtitles/SubtitlesQueueDisplayConverter.cs | 2 +- .../Video/EncoderOptionsTooltipConverter.cs | 8 +- .../Converters/Video/VideoEncoderConverter.cs | 6 +- .../Video/VideoOptionsTooltipConverter.cs | 3 +- win/CS/HandBrakeWPF/HandBrakeWPF.csproj | 36 ++ win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs | 6 +- win/CS/HandBrakeWPF/Model/SelectionTitle.cs | 2 +- win/CS/HandBrakeWPF/Services/Encode/EncodeBase.cs | 380 ++++++++++++ .../Encode/EventArgs/EncodeCompletedEventArgs.cs | 68 +++ .../Encode/EventArgs/EncodeProgressEventArgs.cs | 63 ++ .../Services/Encode/Factories/EncodeFactory.cs | 542 ++++++++++++++++++ .../Services/Encode/Factories/VideoLevelFactory.cs | 38 ++ .../Encode/Factories/VideoPresetFactory.cs | 63 ++ .../Encode/Factories/VideoProfileFactory.cs | 48 ++ .../Services/Encode/Factories/VideoTuneFactory.cs | 54 ++ .../Services/Encode/Interfaces/IEncode.cs | 119 ++++ win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs | 262 +++++++++ .../Services/Encode/Model/EncodeTask.cs | 557 ++++++++++++++++++ .../Encode/Model/Models/AllowedPassthru.cs | 172 ++++++ .../Services/Encode/Model/Models/AudioEncoder.cs | 89 +++ .../Encode/Model/Models/AudioEncoderRateType.cs | 31 + .../Services/Encode/Model/Models/AudioTrack.cs | 636 +++++++++++++++++++++ .../Services/Encode/Model/Models/ChapterMarker.cs | 92 +++ .../Services/Encode/Model/Models/DenoisePreset.cs | 45 ++ .../Services/Encode/Model/Models/DenoiseTune.cs | 41 ++ .../Services/Encode/Model/Models/FramerateMode.cs | 28 + .../Services/Encode/Model/Models/OutputFormat.cs | 32 ++ .../Encode/Model/Models/PointToPointMode.cs | 31 + .../Services/Encode/Model/Models/SubtitleTrack.cs | 275 +++++++++ .../Services/Encode/Model/Models/SubtitleType.cs | 38 ++ .../Encode/Model/Models/Video/VideoLevel.cs | 118 ++++ .../Encode/Model/Models/Video/VideoPreset.cs | 121 ++++ .../Encode/Model/Models/Video/VideoProfile.cs | 121 ++++ .../Encode/Model/Models/Video/VideoTune.cs | 137 +++++ .../HandBrakeWPF/Services/PrePostActionService.cs | 2 +- .../Presets/Factories/JsonPresetFactory.cs | 15 +- .../HandBrakeWPF/Services/Presets/Model/Preset.cs | 5 +- .../HandBrakeWPF/Services/Presets/PresetService.cs | 5 +- .../Services/Queue/Interfaces/IQueueProcessor.cs | 4 +- .../HandBrakeWPF/Services/Queue/Model/QueueTask.cs | 3 +- .../HandBrakeWPF/Services/Queue/QueueProcessor.cs | 4 +- .../Scan/EventArgs/ScanCompletedEventArgs.cs | 70 +++ .../Scan/EventArgs/ScanProgressEventArgs.cs | 39 ++ .../HandBrakeWPF/Services/Scan/Interfaces/IScan.cs | 113 ++++ win/CS/HandBrakeWPF/Services/Scan/LibScan.cs | 600 +++++++++++++++++++ win/CS/HandBrakeWPF/Services/Scan/Model/Audio.cs | 181 ++++++ win/CS/HandBrakeWPF/Services/Scan/Model/Chapter.cs | 70 +++ win/CS/HandBrakeWPF/Services/Scan/Model/Source.cs | 57 ++ .../HandBrakeWPF/Services/Scan/Model/Subtitle.cs | 207 +++++++ win/CS/HandBrakeWPF/Services/Scan/Model/Title.cs | 159 ++++++ win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs | 11 +- .../HandBrakeWPF/ViewModels/AddPresetViewModel.cs | 4 +- .../HandBrakeWPF/ViewModels/AdvancedViewModel.cs | 5 +- win/CS/HandBrakeWPF/ViewModels/AudioViewModel.cs | 10 +- .../HandBrakeWPF/ViewModels/ChaptersViewModel.cs | 7 +- win/CS/HandBrakeWPF/ViewModels/FiltersViewModel.cs | 8 +- .../ViewModels/Interfaces/IAddPresetViewModel.cs | 7 +- .../ViewModels/Interfaces/IMainViewModel.cs | 5 +- .../Interfaces/IQueueSelectionViewModel.cs | 3 +- .../Interfaces/IStaticPreviewViewModel.cs | 5 +- .../ViewModels/Interfaces/ITabInterface.cs | 6 +- win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs | 11 +- win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs | 94 +-- win/CS/HandBrakeWPF/ViewModels/MiniViewModel.cs | 6 +- .../ViewModels/PictureSettingsViewModel.cs | 4 +- .../ViewModels/QueueSelectionViewModel.cs | 3 +- win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs | 6 +- .../ViewModels/StaticPreviewViewModel.cs | 17 +- .../HandBrakeWPF/ViewModels/SubtitlesViewModel.cs | 9 +- win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs | 12 +- win/CS/HandBrakeWPF/ViewModels/X264ViewModel.cs | 6 +- 76 files changed, 5911 insertions(+), 147 deletions(-) create mode 100644 win/CS/HandBrakeWPF/Services/Encode/EncodeBase.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/EventArgs/EncodeCompletedEventArgs.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/EventArgs/EncodeProgressEventArgs.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Factories/EncodeFactory.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Factories/VideoLevelFactory.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Factories/VideoPresetFactory.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Factories/VideoProfileFactory.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Factories/VideoTuneFactory.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Interfaces/IEncode.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/EncodeTask.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/AllowedPassthru.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioEncoder.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioEncoderRateType.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioTrack.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/ChapterMarker.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/DenoisePreset.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/DenoiseTune.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/FramerateMode.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/OutputFormat.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/PointToPointMode.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleTrack.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleType.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoLevel.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoPreset.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoProfile.cs create mode 100644 win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoTune.cs create mode 100644 win/CS/HandBrakeWPF/Services/Scan/EventArgs/ScanCompletedEventArgs.cs create mode 100644 win/CS/HandBrakeWPF/Services/Scan/EventArgs/ScanProgressEventArgs.cs create mode 100644 win/CS/HandBrakeWPF/Services/Scan/Interfaces/IScan.cs create mode 100644 win/CS/HandBrakeWPF/Services/Scan/LibScan.cs create mode 100644 win/CS/HandBrakeWPF/Services/Scan/Model/Audio.cs create mode 100644 win/CS/HandBrakeWPF/Services/Scan/Model/Chapter.cs create mode 100644 win/CS/HandBrakeWPF/Services/Scan/Model/Source.cs create mode 100644 win/CS/HandBrakeWPF/Services/Scan/Model/Subtitle.cs create mode 100644 win/CS/HandBrakeWPF/Services/Scan/Model/Title.cs (limited to 'win/CS/HandBrakeWPF') diff --git a/win/CS/HandBrakeWPF/Converters/Audio/AudioEncoderConverter.cs b/win/CS/HandBrakeWPF/Converters/Audio/AudioEncoderConverter.cs index ff6eaec06..e9bb60fce 100644 --- a/win/CS/HandBrakeWPF/Converters/Audio/AudioEncoderConverter.cs +++ b/win/CS/HandBrakeWPF/Converters/Audio/AudioEncoderConverter.cs @@ -16,10 +16,11 @@ namespace HandBrakeWPF.Converters.Audio using System.Windows; using System.Windows.Data; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; using HandBrake.ApplicationServices.Utilities; - using HandBrake.ApplicationServices.Interop.Model.Encoding; + + using AudioEncoder = HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + using OutputFormat = HandBrakeWPF.Services.Encode.Model.Models.OutputFormat; /// /// Audio Encoder Converter diff --git a/win/CS/HandBrakeWPF/Converters/Audio/AudioQueueDisplayConverter.cs b/win/CS/HandBrakeWPF/Converters/Audio/AudioQueueDisplayConverter.cs index 1cc6af360..d3072e131 100644 --- a/win/CS/HandBrakeWPF/Converters/Audio/AudioQueueDisplayConverter.cs +++ b/win/CS/HandBrakeWPF/Converters/Audio/AudioQueueDisplayConverter.cs @@ -13,12 +13,12 @@ namespace HandBrakeWPF.Converters.Audio using System.Collections.ObjectModel; using System.Globalization; using System.Text; - using System.Threading.Tasks; using System.Windows.Data; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; using HandBrake.ApplicationServices.Utilities; - using HandBrake.ApplicationServices.Interop.Model.Encoding; + + using AudioEncoder = HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder; + using AudioTrack = HandBrakeWPF.Services.Encode.Model.Models.AudioTrack; /// /// Audio Queue Display Converter diff --git a/win/CS/HandBrakeWPF/Converters/Audio/AudioRateTypeConverter.cs b/win/CS/HandBrakeWPF/Converters/Audio/AudioRateTypeConverter.cs index 720414b73..b7e9cd392 100644 --- a/win/CS/HandBrakeWPF/Converters/Audio/AudioRateTypeConverter.cs +++ b/win/CS/HandBrakeWPF/Converters/Audio/AudioRateTypeConverter.cs @@ -14,9 +14,10 @@ namespace HandBrakeWPF.Converters.Audio using System.Globalization; using System.Windows.Data; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; using HandBrake.ApplicationServices.Utilities; + using AudioEncoderRateType = HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType; + /// /// The audio rate type converter. /// diff --git a/win/CS/HandBrakeWPF/Converters/EnumComboConverter.cs b/win/CS/HandBrakeWPF/Converters/EnumComboConverter.cs index a28bf9685..2c9f8bd90 100644 --- a/win/CS/HandBrakeWPF/Converters/EnumComboConverter.cs +++ b/win/CS/HandBrakeWPF/Converters/EnumComboConverter.cs @@ -15,10 +15,10 @@ namespace HandBrakeWPF.Converters using System; using HandBrake.ApplicationServices.Model; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; using HandBrake.ApplicationServices.Utilities; using HandBrake.ApplicationServices.Interop.Model.Encoding; + using OutputFormat = HandBrakeWPF.Services.Encode.Model.Models.OutputFormat; using PresetPictureSettingsMode = HandBrakeWPF.Model.Picture.PresetPictureSettingsMode; /// diff --git a/win/CS/HandBrakeWPF/Converters/Filters/DenoisePresetConverter.cs b/win/CS/HandBrakeWPF/Converters/Filters/DenoisePresetConverter.cs index e3110f688..5e2b7024a 100644 --- a/win/CS/HandBrakeWPF/Converters/Filters/DenoisePresetConverter.cs +++ b/win/CS/HandBrakeWPF/Converters/Filters/DenoisePresetConverter.cs @@ -15,9 +15,10 @@ namespace HandBrakeWPF.Converters.Filters using System.Linq; using System.Windows.Data; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; using HandBrake.ApplicationServices.Interop.Model.Encoding; + using DenoisePreset = HandBrakeWPF.Services.Encode.Model.Models.DenoisePreset; + /// /// The denoise preset converter. /// diff --git a/win/CS/HandBrakeWPF/Converters/Subtitles/SubtitlesQueueDisplayConverter.cs b/win/CS/HandBrakeWPF/Converters/Subtitles/SubtitlesQueueDisplayConverter.cs index d3e66d6bc..f96983347 100644 --- a/win/CS/HandBrakeWPF/Converters/Subtitles/SubtitlesQueueDisplayConverter.cs +++ b/win/CS/HandBrakeWPF/Converters/Subtitles/SubtitlesQueueDisplayConverter.cs @@ -15,7 +15,7 @@ namespace HandBrakeWPF.Converters.Subtitles using System.Text; using System.Windows.Data; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; + using SubtitleTrack = HandBrakeWPF.Services.Encode.Model.Models.SubtitleTrack; /// /// Subtitle Queue Display Converter diff --git a/win/CS/HandBrakeWPF/Converters/Video/EncoderOptionsTooltipConverter.cs b/win/CS/HandBrakeWPF/Converters/Video/EncoderOptionsTooltipConverter.cs index 900d70236..29e668917 100644 --- a/win/CS/HandBrakeWPF/Converters/Video/EncoderOptionsTooltipConverter.cs +++ b/win/CS/HandBrakeWPF/Converters/Video/EncoderOptionsTooltipConverter.cs @@ -14,10 +14,14 @@ namespace HandBrakeWPF.Converters.Video using System.Linq; using System.Windows.Data; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Encode.Model.Models.Video; using HandBrake.ApplicationServices.Interop.Model.Encoding; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + using VideoLevel = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoLevel; + using VideoPreset = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoPreset; + using VideoProfile = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoProfile; + using VideoTune = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoTune; + /// /// The x 264 queue tooltip converter. /// diff --git a/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs b/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs index d0ef60775..a0aba003f 100644 --- a/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs +++ b/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs @@ -15,12 +15,12 @@ namespace HandBrakeWPF.Converters.Video using System.Linq; using System.Windows.Data; - using HandBrake.ApplicationServices.Model; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; using HandBrake.ApplicationServices.Utilities; using HandBrake.ApplicationServices.Interop.Model.Encoding; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + using OutputFormat = HandBrakeWPF.Services.Encode.Model.Models.OutputFormat; + /// /// Video Encoder Converter /// diff --git a/win/CS/HandBrakeWPF/Converters/Video/VideoOptionsTooltipConverter.cs b/win/CS/HandBrakeWPF/Converters/Video/VideoOptionsTooltipConverter.cs index 278d9e960..edf14d6ee 100644 --- a/win/CS/HandBrakeWPF/Converters/Video/VideoOptionsTooltipConverter.cs +++ b/win/CS/HandBrakeWPF/Converters/Video/VideoOptionsTooltipConverter.cs @@ -13,10 +13,11 @@ namespace HandBrakeWPF.Converters.Video using System.Globalization; using System.Windows.Data; - using HandBrake.ApplicationServices.Services.Encode.Model; using HandBrake.ApplicationServices.Utilities; using HandBrake.ApplicationServices.Interop.Model.Encoding; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + /// /// The x 264 queue tooltip converter. /// diff --git a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj index bd638e860..980adffa2 100644 --- a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj +++ b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj @@ -171,6 +171,33 @@ True True + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -185,6 +212,15 @@ + + + + + + + + + diff --git a/win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs b/win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs index febb442ec..18f4a6392 100644 --- a/win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs +++ b/win/CS/HandBrakeWPF/Helpers/AutoNameHelper.cs @@ -15,14 +15,14 @@ namespace HandBrakeWPF.Helpers using Caliburn.Micro; - using HandBrake.ApplicationServices.Model; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; using HandBrake.ApplicationServices.Interop.Model.Encoding; using HandBrakeWPF.Extensions; using HandBrakeWPF.Services.Interfaces; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + using OutputFormat = HandBrakeWPF.Services.Encode.Model.Models.OutputFormat; + /// /// The Destination AutoName Helper /// diff --git a/win/CS/HandBrakeWPF/Model/SelectionTitle.cs b/win/CS/HandBrakeWPF/Model/SelectionTitle.cs index a8abe54f4..3fd2fde89 100644 --- a/win/CS/HandBrakeWPF/Model/SelectionTitle.cs +++ b/win/CS/HandBrakeWPF/Model/SelectionTitle.cs @@ -11,7 +11,7 @@ namespace HandBrakeWPF.Model { using Caliburn.Micro; - using HandBrake.ApplicationServices.Services.Scan.Model; + using HandBrakeWPF.Services.Scan.Model; /// /// A model for the multiple selection window for adding to the queue. diff --git a/win/CS/HandBrakeWPF/Services/Encode/EncodeBase.cs b/win/CS/HandBrakeWPF/Services/Encode/EncodeBase.cs new file mode 100644 index 000000000..83ac7a083 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/EncodeBase.cs @@ -0,0 +1,380 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// A Base Class for the Encode Services. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode +{ + using System; + using System.Diagnostics; + using System.IO; + using System.Text; + + using HandBrake.ApplicationServices.Exceptions; + using HandBrake.ApplicationServices.Model; + using HandBrake.ApplicationServices.Utilities; + + using EncodeCompletedEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs; + using EncodeCompletedStatus = HandBrakeWPF.Services.Encode.Interfaces.EncodeCompletedStatus; + using EncodeProgessStatus = HandBrakeWPF.Services.Encode.Interfaces.EncodeProgessStatus; + using EncodeProgressEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeProgressEventArgs; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + + /// + /// A Base Class for the Encode Services. + /// + public class EncodeBase + { + #region Private Variables + + /// + /// A Lock for the filewriter + /// + private static readonly object FileWriterLock = new object(); + + /// + /// The Log File Header + /// + private readonly StringBuilder header; + + /// + /// The Log Buffer + /// + private StringBuilder logBuffer; + + /// + /// The Log file writer + /// + private StreamWriter fileWriter; + + #endregion + + /// + /// Initializes a new instance of the class. + /// + public EncodeBase() + { + this.logBuffer = new StringBuilder(); + this.header = GeneralUtilities.CreateLogHeader(); + this.LogIndex = 0; + } + + #region Events + + /// + /// Fires when a new QueueTask starts + /// + public event EventHandler EncodeStarted; + + /// + /// Fires when a QueueTask finishes. + /// + public event EncodeCompletedStatus EncodeCompleted; + + /// + /// Encode process has progressed + /// + public event EncodeProgessStatus EncodeStatusChanged; + + #endregion + + #region Properties + + /// + /// Gets or sets a value indicating whether IsEncoding. + /// + public bool IsEncoding { get; protected set; } + + /// + /// Gets ActivityLog. + /// + public string ActivityLog + { + get + { + string noLog = "There is no log information to display." + Environment.NewLine + Environment.NewLine + + "This window will only display logging information after you have started an encode." + Environment.NewLine + + Environment.NewLine + "You can find previous log files in the log directory or by clicking the 'Open Log Directory' button above."; + + return string.IsNullOrEmpty(this.logBuffer.ToString()) + ? noLog + : this.header + this.logBuffer.ToString(); + } + } + + /// + /// Gets the log index. + /// + public int LogIndex { get; private set; } + + /// + /// Gets LogBuffer. + /// + public StringBuilder LogBuffer + { + get + { + return this.logBuffer; + } + } + + #endregion + + #region Invoke Events + + /// + /// Invoke the Encode Status Changed Event. + /// + /// + /// The EncodeProgressEventArgs. + /// + public void InvokeEncodeStatusChanged(EncodeProgressEventArgs e) + { + EncodeProgessStatus handler = this.EncodeStatusChanged; + if (handler != null) + { + handler(this, e); + } + } + + /// + /// Invoke the Encode Completed Event + /// + /// + /// The EncodeCompletedEventArgs. + /// + public void InvokeEncodeCompleted(EncodeCompletedEventArgs e) + { + EncodeCompletedStatus handler = this.EncodeCompleted; + if (handler != null) + { + handler(this, e); + } + + this.LogIndex = 0; // Reset + } + + /// + /// Invoke the Encode Started Event + /// + /// + /// The EventArgs. + /// + public void InvokeEncodeStarted(System.EventArgs e) + { + EventHandler handler = this.EncodeStarted; + if (handler != null) + { + handler(this, e); + } + } + + #endregion + + #region Methods + + /// + /// Save a copy of the log to the users desired location or a default location + /// if this feature is enabled in options. + /// + /// + /// The Destination File Path + /// + /// + /// The configuration. + /// + public void ProcessLogs(string destination, HBConfiguration configuration) + { + try + { + string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + + "\\HandBrake\\logs"; + string tempLogFile = Path.Combine(logDir, string.Format("last_encode_log{0}.txt", GeneralUtilities.ProcessId)); + + string encodeDestinationPath = Path.GetDirectoryName(destination); + string destinationFile = Path.GetFileName(destination); + string encodeLogFile = destinationFile + " " + + DateTime.Now.ToString().Replace("/", "-").Replace(":", "-") + ".txt"; + + // Make sure the log directory exists. + if (!Directory.Exists(logDir)) + { + Directory.CreateDirectory(logDir); + } + + // Copy the Log to HandBrakes log folder in the users applciation data folder. + File.Copy(tempLogFile, Path.Combine(logDir, encodeLogFile)); + + // Save a copy of the log file in the same location as the enocde. + if (configuration.SaveLogWithVideo) + { + File.Copy(tempLogFile, Path.Combine(encodeDestinationPath, encodeLogFile)); + } + + // Save a copy of the log file to a user specified location + if (Directory.Exists(configuration.SaveLogCopyDirectory) && configuration.SaveLogToCopyDirectory) + { + File.Copy( + tempLogFile, Path.Combine(configuration.SaveLogCopyDirectory, encodeLogFile)); + } + } + catch (Exception exc) + { + Debug.WriteLine(exc); // This exception doesn't warrent user interaction, but it should be logged + } + } + + /// + /// Setup the logging. + /// + protected void SetupLogging() + { + this.ShutdownFileWriter(); + string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs"; + string logFile = Path.Combine(logDir, string.Format("last_encode_log{0}.txt", GeneralUtilities.ProcessId)); + string logFile2 = Path.Combine(logDir, string.Format("tmp_appReadable_log{0}.txt", GeneralUtilities.ProcessId)); + + try + { + this.logBuffer = new StringBuilder(); + + this.logBuffer.AppendLine(); + + // Clear the current Encode Logs) + if (File.Exists(logFile)) + { + File.Delete(logFile); + } + + if (File.Exists(logFile2)) + { + File.Delete(logFile2); + } + + lock (FileWriterLock) + { + this.fileWriter = new StreamWriter(logFile) { AutoFlush = true }; + this.fileWriter.WriteLine(this.header); + this.fileWriter.WriteLine(); + } + } + catch (Exception) + { + if (this.fileWriter != null) + { + lock (FileWriterLock) + { + this.fileWriter.Flush(); + this.fileWriter.Close(); + this.fileWriter.Dispose(); + } + } + + throw; + } + } + + /// + /// The service log message. + /// + /// + /// The message. + /// + protected void ServiceLogMessage(string message) + { + this.ProcessLogMessage(string.Format("# {0}", message)); + } + + /// + /// Process an Incomming Log Message. + /// + /// + /// The message. + /// + protected void ProcessLogMessage(string message) + { + if (!string.IsNullOrEmpty(message)) + { + try + { + this.LogIndex = this.LogIndex + 1; + + lock (this.LogBuffer) + { + this.LogBuffer.AppendLine(message); + } + + lock (FileWriterLock) + { + if (this.fileWriter != null && this.fileWriter.BaseStream.CanWrite) + { + this.fileWriter.WriteLine(message); + } + } + } + catch (Exception exc) + { + Debug.WriteLine(exc); // This exception doesn't warrent user interaction, but it should be logged + } + } + } + + /// + /// Shutdown and Dispose of the File Writer. + /// + protected void ShutdownFileWriter() + { + try + { + lock (FileWriterLock) + { + if (this.fileWriter != null) + { + this.fileWriter.Flush(); + this.fileWriter.Close(); + this.fileWriter.Dispose(); + } + + this.fileWriter = null; + } + } + catch (Exception exc) + { + Debug.WriteLine(exc); // This exception doesn't warrent user interaction, but it should be logged + } + } + + /// + /// Verify the Encode Destination path exists and if not, create it. + /// + /// + /// The task. + /// + /// + /// If the creation fails, an exception is thrown. + /// + protected void VerifyEncodeDestinationPath(EncodeTask task) + { + // Make sure the path exists, attempt to create it if it doesn't + try + { + string path = Directory.GetParent(task.Destination).ToString(); + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + } + catch (Exception exc) + { + throw new GeneralApplicationException( + "Unable to create directory for the encoded output.", "Please verify that you have a valid path.", exc); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/Encode/EventArgs/EncodeCompletedEventArgs.cs b/win/CS/HandBrakeWPF/Services/Encode/EventArgs/EncodeCompletedEventArgs.cs new file mode 100644 index 000000000..ea334705d --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/EventArgs/EncodeCompletedEventArgs.cs @@ -0,0 +1,68 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Encode Progress Event Args +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.EventArgs +{ + using System; + using System.Runtime.Serialization; + + /// + /// Encode Progress Event Args + /// + [DataContract] + public class EncodeCompletedEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// + /// The sucessful. + /// + /// + /// The exception. + /// + /// + /// The error information. + /// + /// + /// The filename. + /// + public EncodeCompletedEventArgs(bool sucessful, Exception exception, string errorInformation, string filename) + { + this.Successful = sucessful; + this.Exception = exception; + this.ErrorInformation = errorInformation; + this.FileName = filename; + } + + /// + /// Gets or sets the file name. + /// + [DataMember] + public string FileName { get; set; } + + /// + /// Gets or sets a value indicating whether Successful. + /// + [DataMember] + public bool Successful { get; set; } + + /// + /// Gets or sets Exception. + /// + [DataMember] + public Exception Exception { get; set; } + + /// + /// Gets or sets ErrorInformation. + /// + [DataMember] + public string ErrorInformation { get; set; } + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/EventArgs/EncodeProgressEventArgs.cs b/win/CS/HandBrakeWPF/Services/Encode/EventArgs/EncodeProgressEventArgs.cs new file mode 100644 index 000000000..5d3d12791 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/EventArgs/EncodeProgressEventArgs.cs @@ -0,0 +1,63 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Encode Progress Event Args +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.EventArgs +{ + using System; + using System.Runtime.Serialization; + + /// + /// Encode Progress Event Args + /// + [DataContract] + public class EncodeProgressEventArgs : EventArgs + { + /// + /// Gets or sets PercentComplete. + /// + [DataMember] + public double PercentComplete { get; set; } + + /// + /// Gets or sets CurrentFrameRate. + /// + [DataMember] + public double CurrentFrameRate { get; set; } + + /// + /// Gets or sets AverageFrameRate. + /// + [DataMember] + public double AverageFrameRate { get; set; } + + /// + /// Gets or sets EstimatedTimeLeft. + /// + [DataMember] + public TimeSpan EstimatedTimeLeft { get; set; } + + /// + /// Gets or sets Task. + /// + [DataMember] + public int Task { get; set; } + + /// + /// Gets or sets TaskCount. + /// + [DataMember] + public int TaskCount { get; set; } + + /// + /// Gets or sets ElapsedTime. + /// + [DataMember] + public TimeSpan ElapsedTime { get; set; } + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Factories/EncodeFactory.cs b/win/CS/HandBrakeWPF/Services/Encode/Factories/EncodeFactory.cs new file mode 100644 index 000000000..8c60024f6 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Factories/EncodeFactory.cs @@ -0,0 +1,542 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// The encode factory. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Factories +{ + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Linq; + using System.Runtime.InteropServices; + + using HandBrake.ApplicationServices.Interop; + using HandBrake.ApplicationServices.Interop.HbLib; + using HandBrake.ApplicationServices.Interop.Helpers; + using HandBrake.ApplicationServices.Interop.Json.Encode; + using HandBrake.ApplicationServices.Interop.Json.Shared; + using HandBrake.ApplicationServices.Interop.Model.Encoding; + using HandBrake.ApplicationServices.Model; + using HandBrake.ApplicationServices.Utilities; + + using AudioEncoder = HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder; + using AudioEncoderRateType = HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType; + using AudioTrack = HandBrakeWPF.Services.Encode.Model.Models.AudioTrack; + using ChapterMarker = HandBrakeWPF.Services.Encode.Model.Models.ChapterMarker; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + using FramerateMode = HandBrakeWPF.Services.Encode.Model.Models.FramerateMode; + using OutputFormat = HandBrakeWPF.Services.Encode.Model.Models.OutputFormat; + using PointToPointMode = HandBrakeWPF.Services.Encode.Model.Models.PointToPointMode; + using Subtitle = HandBrake.ApplicationServices.Interop.Json.Encode.Subtitles; + using SubtitleTrack = HandBrakeWPF.Services.Encode.Model.Models.SubtitleTrack; + + /// + /// This factory takes the internal EncodeJob object and turns it into a set of JSON models + /// that can be deserialized by libhb. + /// + internal class EncodeFactory + { + /* + * TODO: + * 1. OpenCL and HWD Support + * 2. Rotate Support + */ + + /// + /// The create. + /// + /// + /// The encode job. + /// + /// + /// The configuration. + /// + /// + /// The . + /// + internal static JsonEncodeObject Create(EncodeTask job, HBConfiguration configuration) + { + JsonEncodeObject encode = new JsonEncodeObject + { + SequenceID = 0, + Audio = CreateAudio(job), + Destination = CreateDestination(job), + Filters = CreateFilters(job), + PAR = CreatePAR(job), + Metadata = CreateMetadata(job), + Source = CreateSource(job, configuration), + Subtitle = CreateSubtitle(job), + Video = CreateVideo(job, configuration) + }; + + return encode; + } + + /// + /// The create source. + /// + /// + /// The job. + /// + /// + /// The configuration. + /// + /// + /// The . + /// + private static Source CreateSource(EncodeTask job, HBConfiguration configuration) + { + Range range = new Range(); + switch (job.PointToPointMode) + { + case PointToPointMode.Chapters: + range.Type = "chapter"; + range.Start = job.StartPoint; + range.End = job.EndPoint; + break; + case PointToPointMode.Seconds: + range.Type = "time"; + range.Start = job.StartPoint * 90000; + range.End = (job.EndPoint - job.StartPoint) * 90000; + break; + case PointToPointMode.Frames: + range.Type = "frame"; + range.Start = job.StartPoint; + range.End = job.EndPoint; + break; + case PointToPointMode.Preview: + range.Type = "preview"; + range.Start = job.PreviewEncodeStartAt; + range.SeekPoints = configuration.PreviewScanCount; + range.End = job.PreviewEncodeDuration * 90000; + break; + } + + Source source = new Source + { + Title = job.Title, + Range = range, + Angle = job.Angle, + Path = job.Source, + }; + return source; + } + + /// + /// The create destination. + /// + /// + /// The job. + /// + /// + /// The . + /// + private static Destination CreateDestination(EncodeTask job) + { + Destination destination = new Destination + { + File = job.Destination, + Mp4Options = new Mp4Options + { + IpodAtom = job.IPod5GSupport, + Mp4Optimize = job.OptimizeMP4 + }, + ChapterMarkers = job.IncludeChapterMarkers, + Mux = HBFunctions.hb_container_get_from_name(job.OutputFormat == OutputFormat.Mp4 ? "av_mp4" : "av_mkv"), // TODO tidy up. + ChapterList = new List() + }; + + if (job.IncludeChapterMarkers) + { + foreach (ChapterMarker item in job.ChapterNames) + { + Chapter chapter = new Chapter { Name = item.ChapterName }; + destination.ChapterList.Add(chapter); + } + } + + return destination; + } + + /// + /// Create the PAR object + /// + /// + /// The Job + /// + /// + /// The produced PAR object. + /// + private static PAR CreatePAR(EncodeTask job) + { + return new PAR { Num = job.PixelAspectX, Den = job.PixelAspectY }; + } + + /// + /// The create subtitle. + /// + /// + /// The job. + /// + /// + /// The . + /// + private static Subtitle CreateSubtitle(EncodeTask job) + { + Subtitles subtitle = new Subtitles + { + Search = + new SubtitleSearch + { + Enable = false, + Default = false, + Burn = false, + Forced = false + }, + SubtitleList = new List() + }; + + foreach (SubtitleTrack item in job.SubtitleTracks) + { + if (!item.IsSrtSubtitle) + { + // Handle Foreign Audio Search + if (item.SourceTrack.TrackNumber == 0) + { + subtitle.Search.Enable = true; + subtitle.Search.Burn = item.Burned; + subtitle.Search.Default = item.Default; + subtitle.Search.Forced = item.Forced; + } + else + { + HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack track = new HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack + { + Burn = item.Burned, + Default = item.Default, + Forced = item.Forced, + ID = item.SourceTrack.TrackNumber, + Track = (item.SourceTrack.TrackNumber - 1) + }; + + subtitle.SubtitleList.Add(track); + } + } + else + { + HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack track = new HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack + { + Track = -1, // Indicates SRT + Default = item.Default, + Offset = item.SrtOffset, + Burn = item.Burned, + SRT = + new SRT + { + Filename = item.SrtPath, + Codeset = item.SrtCharCode, + Language = item.SrtLang + } + }; + + subtitle.SubtitleList.Add(track); + } + } + + return subtitle; + } + + /// + /// The create video. + /// + /// + /// The job. + /// + /// + /// The configuration. + /// + /// + /// The . + /// + private static Video CreateVideo(EncodeTask job, HBConfiguration configuration) + { + Video video = new Video(); + + HBVideoEncoder videoEncoder = HandBrakeEncoderHelpers.VideoEncoders.FirstOrDefault(e => e.ShortName == EnumHelper.GetShortName(job.VideoEncoder)); + Validate.NotNull(videoEncoder, "Video encoder " + job.VideoEncoder + " not recognized."); + if (videoEncoder != null) + { + video.Encoder = videoEncoder.Id; + } + + string advancedOptions = job.ShowAdvancedTab ? job.AdvancedEncoderOptions : string.Empty; + if (!string.IsNullOrEmpty(advancedOptions)) + { + video.Options = advancedOptions; + } + else + { + video.Level = job.VideoLevel != null ? job.VideoLevel.ShortName : null; + video.Options = job.ExtraAdvancedArguments; + video.Preset = job.VideoPreset != null ? job.VideoPreset.ShortName : null; + video.Profile = job.VideoProfile != null ? job.VideoProfile.ShortName : null; + } + + if (job.VideoEncodeRateType == VideoEncodeRateType.ConstantQuality) video.Quality = job.Quality; + if (job.VideoEncodeRateType == VideoEncodeRateType.AverageBitrate) + { + video.Bitrate = job.VideoBitrate; + video.TwoPass = job.TwoPass; + video.Turbo = job.TurboFirstPass; + } + + if (job.VideoTunes != null && job.VideoTunes.Count > 0) + { + foreach (var item in job.VideoTunes) + { + video.Tune += string.IsNullOrEmpty(video.Tune) ? item.ShortName : "," + item.ShortName; + } + } + + video.OpenCL = configuration.ScalingMode == VideoScaler.BicubicCl; + video.HWDecode = configuration.EnableDxva; + video.QSV.Decode = !configuration.DisableQuickSyncDecoding; + + return video; + } + + /// + /// The create audio. + /// + /// + /// The job. + /// + /// + /// The . + /// + private static Audio CreateAudio(EncodeTask job) + { + Audio audio = new Audio(); + + List copyMaskList = new List(); + if (job.AllowedPassthruOptions.AudioAllowAACPass) copyMaskList.Add(NativeConstants.HB_ACODEC_AAC_PASS); + if (job.AllowedPassthruOptions.AudioAllowAC3Pass) copyMaskList.Add(NativeConstants.HB_ACODEC_AC3_PASS); + if (job.AllowedPassthruOptions.AudioAllowDTSHDPass) copyMaskList.Add(NativeConstants.HB_ACODEC_DCA_HD_PASS); + if (job.AllowedPassthruOptions.AudioAllowDTSPass) copyMaskList.Add(NativeConstants.HB_ACODEC_DCA_PASS); + if (job.AllowedPassthruOptions.AudioAllowEAC3Pass) copyMaskList.Add(NativeConstants.HB_ACODEC_EAC3_PASS); + if (job.AllowedPassthruOptions.AudioAllowFlacPass) copyMaskList.Add(NativeConstants.HB_ACODEC_FLAC_PASS); + if (job.AllowedPassthruOptions.AudioAllowMP3Pass) copyMaskList.Add(NativeConstants.HB_ACODEC_MP3_PASS); + if (job.AllowedPassthruOptions.AudioAllowTrueHDPass) copyMaskList.Add(NativeConstants.HB_ACODEC_TRUEHD_PASS); + audio.CopyMask = copyMaskList.ToArray(); + + HBAudioEncoder audioEncoder = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper.GetShortName(job.AllowedPassthruOptions.AudioEncoderFallback)); + audio.FallbackEncoder = audioEncoder.Id; + + audio.AudioList = new List(); + foreach (AudioTrack item in job.AudioTracks) + { + HBAudioEncoder encoder = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper.GetShortName(item.Encoder)); + Validate.NotNull(encoder, "Unrecognized audio encoder:" + item.Encoder); + + HBMixdown mixdown = HandBrakeEncoderHelpers.GetMixdown(EnumHelper.GetShortName(item.MixDown)); + Validate.NotNull(mixdown, "Unrecognized audio mixdown:" + item.MixDown); + + HBRate sampleRate = HandBrakeEncoderHelpers.AudioSampleRates.FirstOrDefault(s => s.Name == item.SampleRate.ToString(CultureInfo.InvariantCulture)); + + HandBrake.ApplicationServices.Interop.Json.Encode.AudioTrack audioTrack = new HandBrake.ApplicationServices.Interop.Json.Encode.AudioTrack + { + Track = (item.Track.HasValue ? item.Track.Value : 0) - 1, + DRC = item.DRC, + Encoder = encoder.Id, + Gain = item.Gain, + Mixdown = mixdown.Id, + NormalizeMixLevel = false, + Samplerate = sampleRate != null ? sampleRate.Rate : 0, + Name = item.TrackName, + }; + + if (!item.IsPassthru) + { + if (item.EncoderRateType == AudioEncoderRateType.Quality) + { + audioTrack.Quality = item.Quality; + } + + if (item.EncoderRateType == AudioEncoderRateType.Bitrate) + { + audioTrack.Bitrate = item.Bitrate; + } + } + + audio.AudioList.Add(audioTrack); + } + + return audio; + } + + /// + /// The create filter. + /// + /// + /// The job. + /// + /// + /// The . + /// + private static Filters CreateFilters(EncodeTask job) + { + Filters filter = new Filters + { + FilterList = new List(), + Grayscale = job.Grayscale + }; + + // Detelecine + if (job.Detelecine != Detelecine.Off) + { + Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DETELECINE, Settings = job.CustomDetelecine }; + filter.FilterList.Add(filterItem); + } + + // Decomb + if (job.Decomb != Decomb.Off) + { + string options; + if (job.Decomb == Decomb.Fast) + { + options = "7:2:6:9:1:80"; + } + else if (job.Decomb == Decomb.Bob) + { + options = "455"; + } + else + { + options = job.CustomDecomb; + } + + Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DECOMB, Settings = options }; + filter.FilterList.Add(filterItem); + } + + // Deinterlace + if (job.Deinterlace != Deinterlace.Off) + { + string options; + if (job.Deinterlace == Deinterlace.Fast) + { + options = "0"; + } + else if (job.Deinterlace == Deinterlace.Slow) + { + options = "1"; + } + else if (job.Deinterlace == Deinterlace.Slower) + { + options = "3"; + } + else if (job.Deinterlace == Deinterlace.Bob) + { + options = "15"; + } + else + { + options = job.CustomDeinterlace; + } + + Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DEINTERLACE, Settings = options }; + filter.FilterList.Add(filterItem); + } + + // VFR / CFR + int fm = job.FramerateMode == FramerateMode.CFR ? 1 : job.FramerateMode == FramerateMode.PFR ? 2 : 0; + IntPtr frameratePrt = Marshal.StringToHGlobalAnsi(job.Framerate.ToString()); // TODO check culture + int vrate = HBFunctions.hb_video_framerate_get_from_name(frameratePrt); + + int? num = null; + int? den = null; + if (vrate > 0) + { + num = 27000000; + den = vrate; + } + + string framerateString = num.HasValue ? string.Format("{0}:{1}:{2}", fm, num, den) : string.Format("{0}", fm); // filter_cfr, filter_vrate.num, filter_vrate.den + + Filter framerateShaper = new Filter { ID = (int)hb_filter_ids.HB_FILTER_VFR, Settings = framerateString }; + filter.FilterList.Add(framerateShaper); + + // Deblock + if (job.Deblock >= 5) + { + Filter filterItem = new Filter { ID = (int)hb_filter_ids.HB_FILTER_DEBLOCK, Settings = job.Deblock.ToString() }; + filter.FilterList.Add(filterItem); + } + + // Denoise + if (job.Denoise != Denoise.Off) + { + hb_filter_ids id = job.Denoise == Denoise.hqdn3d + ? hb_filter_ids.HB_FILTER_HQDN3D + : hb_filter_ids.HB_FILTER_NLMEANS; + + string settings; + if (!string.IsNullOrEmpty(job.CustomDenoise)) + { + settings = job.CustomDenoise; + } + else + { + IntPtr settingsPtr = HBFunctions.hb_generate_filter_settings((int)id, job.DenoisePreset.ToString().ToLower().Replace(" ", string.Empty), job.DenoiseTune.ToString().ToLower().Replace(" ", string.Empty)); + settings = Marshal.PtrToStringAnsi(settingsPtr); + } + + Filter filterItem = new Filter { ID = (int)id, Settings = settings }; + filter.FilterList.Add(filterItem); + } + + // CropScale Filter + Filter cropScale = new Filter + { + ID = (int)hb_filter_ids.HB_FILTER_CROP_SCALE, + Settings = + string.Format( + "{0}:{1}:{2}:{3}:{4}:{5}", + job.Width, + job.Height, + job.Cropping.Top, + job.Cropping.Bottom, + job.Cropping.Left, + job.Cropping.Right) + }; + filter.FilterList.Add(cropScale); + + // Rotate + /* TODO NOT SUPPORTED YET. */ + + return filter; + } + + /// + /// The create meta data. + /// + /// + /// The job. + /// + /// + /// The . + /// + private static Metadata CreateMetadata(EncodeTask job) + { + Metadata metaData = new Metadata(); + + /* TODO NOT SUPPORTED YET. */ + return metaData; + } + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Factories/VideoLevelFactory.cs b/win/CS/HandBrakeWPF/Services/Encode/Factories/VideoLevelFactory.cs new file mode 100644 index 000000000..f233d203e --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Factories/VideoLevelFactory.cs @@ -0,0 +1,38 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// The video level factory. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Factories +{ + /// + /// The video tune factory. + /// + public class VideoLevelFactory + { + /// + /// The get display name for a given short name. + /// LibHB doesn't currently support this. + /// + /// + /// The short name. + /// + /// + /// The . + /// + public static string GetDisplayName(string shortName) + { + switch (shortName) + { + case "auto": + return "Auto"; + } + + return shortName; + } + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Factories/VideoPresetFactory.cs b/win/CS/HandBrakeWPF/Services/Encode/Factories/VideoPresetFactory.cs new file mode 100644 index 000000000..491eb7c4e --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Factories/VideoPresetFactory.cs @@ -0,0 +1,63 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// The video preset factory. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Factories +{ + /// + /// The video tune factory. + /// + public class VideoPresetFactory + { + /// + /// The get display name for a given short name. + /// LibHB doesn't currently support this. + /// + /// + /// The short name. + /// + /// + /// The . + /// + public static string GetDisplayName(string shortName) + { + switch (shortName) + { + case "ultrafast": + return "Ultrafast"; + case "superfast": + return "Superfast"; + case "veryfast": + return "Veryfast"; + case "faster": + return "Faster"; + case "fast": + return "Fast"; + case "medium": + return "Medium"; + case "slow": + return "Slow"; + case "slower": + return "Slower"; + case "veryslow": + return "VerySlow"; + case "placebo": + return "Placebo"; + + case "balanced": + return "Balanced"; + case "speed": + return "Speed"; + case "quality": + return "Quality"; + } + + return shortName; + } + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Factories/VideoProfileFactory.cs b/win/CS/HandBrakeWPF/Services/Encode/Factories/VideoProfileFactory.cs new file mode 100644 index 000000000..e9e5c7c75 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Factories/VideoProfileFactory.cs @@ -0,0 +1,48 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// The video profile factory. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Factories +{ + /// + /// The video profile factory. + /// + public class VideoProfileFactory + { + /// + /// The get display name for a given short name. + /// LibHB doesn't currently support this. + /// + /// + /// The short name. + /// + /// + /// The . + /// + public static string GetDisplayName(string shortName) + { + switch (shortName) + { + case "auto": + return "Auto"; + case "main": + return "Main"; + case "high": + return "High"; + case "baseline": + return "Baseline"; + case "main10": + return "Main 10"; + case "mainstillpicture": + return "Main Still Picture"; + } + + return shortName; + } + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Factories/VideoTuneFactory.cs b/win/CS/HandBrakeWPF/Services/Encode/Factories/VideoTuneFactory.cs new file mode 100644 index 000000000..b221ceef6 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Factories/VideoTuneFactory.cs @@ -0,0 +1,54 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// The video tune factory. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Factories +{ + /// + /// The video tune factory. + /// + public class VideoTuneFactory + { + /// + /// The get display name for a given short name. + /// LibHB doesn't currently support this. + /// + /// + /// The short name. + /// + /// + /// The . + /// + public static string GetDisplayName(string shortName) + { + switch (shortName) + { + case "auto": + return "Auto"; + case "film": + return "Film"; + case "animation": + return "Animation"; + case "grain": + return "Grain"; + case "stillimage": + return "Still Image"; + case "psnr": + return "PSNR"; + case "ssim": + return "SSIM"; + case "fastdecode": + return "Fast Decode"; + case "zerolatency": + return "Zero Latency"; + } + + return shortName; + } + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Interfaces/IEncode.cs b/win/CS/HandBrakeWPF/Services/Encode/Interfaces/IEncode.cs new file mode 100644 index 000000000..1e81ed5ed --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Interfaces/IEncode.cs @@ -0,0 +1,119 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Encode Progess Status +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Interfaces +{ + using System; + + using HandBrake.ApplicationServices.Model; + + using EncodeCompletedEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs; + using EncodeProgressEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeProgressEventArgs; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + + /// + /// Encode Progess Status + /// + /// + /// The sender. + /// + /// + /// The EncodeProgressEventArgs. + /// + public delegate void EncodeProgessStatus(object sender, EncodeProgressEventArgs e); + + /// + /// Encode Progess Status + /// + /// + /// The sender. + /// + /// + /// The EncodeProgressEventArgs. + /// + public delegate void EncodeCompletedStatus(object sender, EncodeCompletedEventArgs e); + + /// + /// The IEncode Interface + /// + public interface IEncode + { + /// + /// Fires when a new Job starts + /// + event EventHandler EncodeStarted; + + /// + /// Fires when a job finishes. + /// + event EncodeCompletedStatus EncodeCompleted; + + /// + /// Encode process has progressed + /// + event EncodeProgessStatus EncodeStatusChanged; + + /// + /// Gets a value indicating whether IsEncoding. + /// + bool IsEncoding { get; } + + /// + /// Gets ActivityLog. + /// + string ActivityLog { get; } + + /// + /// Gets the log index. The current log row counter. + /// + int LogIndex { get; } + + /// + /// Gets a value indicating whether is pasued. + /// + bool IsPasued { get; } + + /// + /// Start with a LibHb EncodeJob Object + /// + /// + /// The job. + /// + /// + /// The configuration. + /// + void Start(EncodeTask job, HBConfiguration configuration); + + /// + /// The pause. + /// + void Pause(); + + /// + /// The resume. + /// + void Resume(); + + /// + /// Kill the process + /// + void Stop(); + + /// + /// Copy the log file to the desired destinations + /// + /// + /// The destination. + /// + /// + /// The configuration. + /// + void ProcessLogs(string destination, HBConfiguration configuration); + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs b/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs new file mode 100644 index 000000000..caf1eff1d --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs @@ -0,0 +1,262 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// LibHB Implementation of IEncode +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode +{ + using System; + using System.Diagnostics; + + using HandBrake.ApplicationServices.Interop; + using HandBrake.ApplicationServices.Interop.EventArgs; + using HandBrake.ApplicationServices.Interop.Interfaces; + using HandBrake.ApplicationServices.Model; + + using HandBrakeWPF.Services.Encode.Factories; + + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + using IEncode = HandBrakeWPF.Services.Encode.Interfaces.IEncode; + + /// + /// LibHB Implementation of IEncode + /// + public class LibEncode : HandBrakeWPF.Services.Encode.EncodeBase, IEncode + { + #region Private Variables + + private static readonly object LogLock = new object(); + private IHandBrakeInstance instance; + private DateTime startTime; + private EncodeTask currentTask; + private HBConfiguration currentConfiguration; + + #endregion + + /// + /// Gets a value indicating whether is pasued. + /// + public bool IsPasued { get; private set; } + + /// + /// Start with a LibHb EncodeJob Object + /// + /// + /// The task. + /// + /// + /// The configuration. + /// + public void Start(EncodeTask task, HBConfiguration configuration) + { + try + { + // Setup + this.startTime = DateTime.Now; + this.currentTask = task; + this.currentConfiguration = configuration; + + // Create a new HandBrake instance + // Setup the HandBrake Instance + HandBrakeUtils.MessageLogged += this.HandBrakeInstanceMessageLogged; + HandBrakeUtils.ErrorLogged += this.HandBrakeInstanceErrorLogged; + this.instance = HandBrakeInstanceManager.GetEncodeInstance(configuration.Verbosity); + this.instance.EncodeCompleted += this.InstanceEncodeCompleted; + this.instance.EncodeProgress += this.InstanceEncodeProgress; + + // Sanity Checking and Setup + if (this.IsEncoding) + { + throw new Exception("HandBrake is already encoding."); + } + + this.IsEncoding = true; + this.SetupLogging(); + + // Verify the Destination Path Exists, and if not, create it. + this.VerifyEncodeDestinationPath(task); + + this.ServiceLogMessage("Starting Encode ..."); + + // Get an EncodeJob object for the Interop Library + this.instance.StartEncode(EncodeFactory.Create(task, configuration)); + + // Fire the Encode Started Event + this.InvokeEncodeStarted(System.EventArgs.Empty); + + // Set the Process Priority + switch (configuration.ProcessPriority) + { + case "Realtime": + Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime; + break; + case "High": + Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High; + break; + case "Above Normal": + Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.AboveNormal; + break; + case "Normal": + Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.Normal; + break; + case "Low": + Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.Idle; + break; + default: + Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal; + break; + } + } + catch (Exception exc) + { + this.IsEncoding = false; + + this.ServiceLogMessage("Failed to start encoding ..." + Environment.NewLine + exc); + this.InvokeEncodeCompleted(new HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs(false, exc, "Unable to start encoding", task.Source)); + } + } + + /// + /// Pause the currently running encode. + /// + public void Pause() + { + if (this.instance != null) + { + this.instance.PauseEncode(); + this.ServiceLogMessage("Encode Paused"); + this.IsPasued = true; + } + } + + /// + /// Resume the currently running encode. + /// + public void Resume() + { + if (this.instance != null) + { + this.instance.ResumeEncode(); + this.ServiceLogMessage("Encode Resumed"); + this.IsPasued = false; + } + } + + /// + /// Kill the process + /// + public void Stop() + { + try + { + this.IsEncoding = false; + if (this.instance != null) + { + this.instance.StopEncode(); + this.ServiceLogMessage("Encode Stopped"); + } + } + catch (Exception exc) + { + Debug.WriteLine(exc); + } + } + + #region HandBrakeInstance Event Handlers. + + /// + /// Log a message + /// + /// + /// The sender. + /// + /// + /// The MessageLoggedEventArgs. + /// + private void HandBrakeInstanceErrorLogged(object sender, MessageLoggedEventArgs e) + { + lock (LogLock) + { + this.ProcessLogMessage(e.Message); + } + } + + /// + /// Log a message + /// + /// + /// The sender. + /// + /// + /// The MessageLoggedEventArgs. + /// + private void HandBrakeInstanceMessageLogged(object sender, MessageLoggedEventArgs e) + { + lock (LogLock) + { + this.ProcessLogMessage(e.Message); + } + } + + /// + /// Encode Progress Event Handler + /// + /// + /// The sender. + /// + /// + /// The Interop.EncodeProgressEventArgs. + /// + private void InstanceEncodeProgress(object sender, EncodeProgressEventArgs e) + { + HandBrakeWPF.Services.Encode.EventArgs.EncodeProgressEventArgs args = new HandBrakeWPF.Services.Encode.EventArgs.EncodeProgressEventArgs + { + AverageFrameRate = e.AverageFrameRate, + CurrentFrameRate = e.CurrentFrameRate, + EstimatedTimeLeft = e.EstimatedTimeLeft, + PercentComplete = e.FractionComplete * 100, + Task = e.Pass, + TaskCount = e.PassCount, + ElapsedTime = DateTime.Now - this.startTime, + }; + + this.InvokeEncodeStatusChanged(args); + } + + /// + /// Encode Completed Event Handler + /// + /// + /// The sender. + /// + /// + /// The e. + /// + private void InstanceEncodeCompleted(object sender, EncodeCompletedEventArgs e) + { + this.IsEncoding = false; + this.ServiceLogMessage("Encode Completed ..."); + + // Stop Logging. + HandBrakeUtils.MessageLogged -= this.HandBrakeInstanceMessageLogged; + HandBrakeUtils.ErrorLogged -= this.HandBrakeInstanceErrorLogged; + + // Handling Log Data + this.ProcessLogs(this.currentTask.Destination, this.currentConfiguration); + + // Cleanup + this.ShutdownFileWriter(); + + // Raise the Encode Completed EVent. + this.InvokeEncodeCompleted( + e.Error + ? new HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs(false, null, string.Empty, this.currentTask.Destination) + : new HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs(true, null, string.Empty, this.currentTask.Destination)); + } + #endregion + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/EncodeTask.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/EncodeTask.cs new file mode 100644 index 000000000..e40def17f --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/EncodeTask.cs @@ -0,0 +1,557 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// An Encode Task +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model +{ + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Linq; + + using HandBrake.ApplicationServices.Interop.Model; + using HandBrake.ApplicationServices.Interop.Model.Encoding; + using HandBrake.ApplicationServices.Utilities; + + using AllowedPassthru = HandBrakeWPF.Services.Encode.Model.Models.AllowedPassthru; + using AudioEncoder = HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder; + using AudioTrack = HandBrakeWPF.Services.Encode.Model.Models.AudioTrack; + using ChapterMarker = HandBrakeWPF.Services.Encode.Model.Models.ChapterMarker; + using DenoisePreset = HandBrakeWPF.Services.Encode.Model.Models.DenoisePreset; + using DenoiseTune = HandBrakeWPF.Services.Encode.Model.Models.DenoiseTune; + using FramerateMode = HandBrakeWPF.Services.Encode.Model.Models.FramerateMode; + using OutputFormat = HandBrakeWPF.Services.Encode.Model.Models.OutputFormat; + using PointToPointMode = HandBrakeWPF.Services.Encode.Model.Models.PointToPointMode; + using SubtitleTrack = HandBrakeWPF.Services.Encode.Model.Models.SubtitleTrack; + using SubtitleType = HandBrakeWPF.Services.Encode.Model.Models.SubtitleType; + using VideoLevel = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoLevel; + using VideoPreset = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoPreset; + using VideoProfile = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoProfile; + using VideoTune = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoTune; + + /// + /// An Encode Task + /// + public class EncodeTask : PropertyChangedBase + { + #region Private Fields + + /// + /// The advanced panel enabled. + /// + private bool showAdvancedTab; + + #endregion + + /// + /// Initializes a new instance of the class. + /// + public EncodeTask() + { + this.Cropping = new Cropping(); + this.AudioTracks = new ObservableCollection(); + this.SubtitleTracks = new ObservableCollection(); + this.ChapterNames = new ObservableCollection(); + this.AllowedPassthruOptions = new AllowedPassthru(); + this.Modulus = 16; + + this.VideoTunes = new List(); + } + + /// + /// Initializes a new instance of the class. + /// Copy Constructor + /// + /// + /// The task. + /// + public EncodeTask(EncodeTask task) + { + this.AdvancedEncoderOptions = task.AdvancedEncoderOptions; + this.AllowedPassthruOptions = new AllowedPassthru(task.AllowedPassthruOptions); + this.Anamorphic = task.Anamorphic; + this.Angle = task.Angle; + + this.AudioTracks = new ObservableCollection(); + foreach (AudioTrack track in task.AudioTracks) + { + this.AudioTracks.Add(new AudioTrack(track, true)); + } + + this.ChapterNames = new ObservableCollection(); + foreach (ChapterMarker track in task.ChapterNames) + { + this.ChapterNames.Add(new ChapterMarker(track)); + } + + this.ChapterMarkersFilePath = task.ChapterMarkersFilePath; + this.Cropping = new Cropping(task.Cropping); + this.CustomDecomb = task.CustomDecomb; + this.CustomDeinterlace = task.CustomDeinterlace; + this.CustomDenoise = task.CustomDenoise; + this.CustomDetelecine = task.CustomDetelecine; + this.Deblock = task.Deblock; + this.Decomb = task.Decomb; + this.Deinterlace = task.Deinterlace; + this.Denoise = task.Denoise; + this.DenoisePreset = task.DenoisePreset; + this.DenoiseTune = task.DenoiseTune; + this.Destination = task.Destination; + this.Detelecine = task.Detelecine; + this.DisplayWidth = task.DisplayWidth; + this.EndPoint = task.EndPoint; + this.Framerate = task.Framerate; + this.FramerateMode = task.FramerateMode; + this.Grayscale = task.Grayscale; + this.HasCropping = task.HasCropping; + this.Height = task.Height; + this.IncludeChapterMarkers = task.IncludeChapterMarkers; + this.IPod5GSupport = task.IPod5GSupport; + this.KeepDisplayAspect = task.KeepDisplayAspect; + this.MaxHeight = task.MaxHeight; + this.MaxWidth = task.MaxWidth; + this.Modulus = task.Modulus; + this.OptimizeMP4 = task.OptimizeMP4; + this.OutputFormat = task.OutputFormat; + this.PixelAspectX = task.PixelAspectX; + this.PixelAspectY = task.PixelAspectY; + this.PointToPointMode = task.PointToPointMode; + this.Quality = task.Quality; + this.Source = task.Source; + this.StartPoint = task.StartPoint; + + this.SubtitleTracks = new ObservableCollection(); + foreach (SubtitleTrack subtitleTrack in task.SubtitleTracks) + { + this.SubtitleTracks.Add(new SubtitleTrack(subtitleTrack)); + } + + this.Title = task.Title; + this.TurboFirstPass = task.TurboFirstPass; + this.TwoPass = task.TwoPass; + this.VideoBitrate = task.VideoBitrate; + this.VideoEncoder = task.VideoEncoder; + this.VideoEncodeRateType = task.VideoEncodeRateType; + this.Width = task.Width; + + this.VideoLevel = task.VideoLevel; + this.VideoProfile = task.VideoProfile; + this.VideoPreset = task.VideoPreset; + this.VideoTunes = task.VideoTunes; + this.ExtraAdvancedArguments = task.ExtraAdvancedArguments; + + this.ShowAdvancedTab = task.ShowAdvancedTab; + } + + #region Source + + /// + /// Gets or sets Source. + /// + public string Source { get; set; } + + /// + /// Gets or sets Title. + /// + public int Title { get; set; } + + /// + /// Gets or sets the Angle + /// + public int Angle { get; set; } + + /// + /// Gets or sets PointToPointMode. + /// + public PointToPointMode PointToPointMode { get; set; } + + /// + /// Gets or sets StartPoint. + /// + public int StartPoint { get; set; } + + /// + /// Gets or sets EndPoint. + /// + public int EndPoint { get; set; } + + #endregion + + #region Destination + + /// + /// Gets or sets Destination. + /// + public string Destination { get; set; } + + #endregion + + #region Output Settings + + /// + /// Gets or sets OutputFormat. + /// + public OutputFormat OutputFormat { get; set; } + + /// + /// Gets or sets a value indicating whether Optimize. + /// + public bool OptimizeMP4 { get; set; } + + /// + /// Gets or sets a value indicating whether IPod5GSupport. + /// + public bool IPod5GSupport { get; set; } + + #endregion + + #region Picture + + /// + /// Gets or sets Width. + /// + public int? Width { get; set; } + + /// + /// Gets or sets Height. + /// + public int? Height { get; set; } + + /// + /// Gets or sets MaxWidth. + /// + public int? MaxWidth { get; set; } + + /// + /// Gets or sets MaxHeight. + /// + public int? MaxHeight { get; set; } + + /// + /// Gets or sets Cropping. + /// + public Cropping Cropping { get; set; } + + /// + /// Gets or sets a value indicating whether HasCropping. + /// + public bool HasCropping { get; set; } + + /// + /// Gets or sets Anamorphic. + /// + public Anamorphic Anamorphic { get; set; } + + /// + /// Gets or sets DisplayWidth. + /// + public double? DisplayWidth { get; set; } + + /// + /// Gets or sets a value indicating whether KeepDisplayAspect. + /// + public bool KeepDisplayAspect { get; set; } + + /// + /// Gets or sets PixelAspectX. + /// + public int PixelAspectX { get; set; } + + /// + /// Gets or sets PixelAspectY. + /// + public int PixelAspectY { get; set; } + + /// + /// Gets or sets Modulus. + /// + public int? Modulus { get; set; } + + #endregion + + #region Filters + + /// + /// Gets or sets Deinterlace. + /// + public Deinterlace Deinterlace { get; set; } + + /// + /// Gets or sets CustomDeinterlace. + /// + public string CustomDeinterlace { get; set; } + + /// + /// Gets or sets Decomb. + /// + public Decomb Decomb { get; set; } + + /// + /// Gets or sets CustomDecomb. + /// + public string CustomDecomb { get; set; } + + /// + /// Gets or sets Detelecine. + /// + public Detelecine Detelecine { get; set; } + + /// + /// Gets or sets CustomDetelecine. + /// + public string CustomDetelecine { get; set; } + + /// + /// Gets or sets Denoise. + /// + public Denoise Denoise { get; set; } + + /// + /// Gets or sets the denoise preset. + /// + public DenoisePreset DenoisePreset { get; set; } + + /// + /// Gets or sets the denoise tune. + /// + public DenoiseTune DenoiseTune { get; set; } + + /// + /// Gets or sets CustomDenoise. + /// + public string CustomDenoise { get; set; } + + /// + /// Gets or sets Deblock. + /// + public int Deblock { get; set; } + + /// + /// Gets or sets a value indicating whether Grayscale. + /// + public bool Grayscale { get; set; } + + #endregion + + #region Video + + /// + /// Gets or sets VideoEncodeRateType. + /// + public VideoEncodeRateType VideoEncodeRateType { get; set; } + + /// + /// Gets or sets the VideoEncoder + /// + public VideoEncoder VideoEncoder { get; set; } + + /// + /// Gets or sets the Video Encode Mode + /// + public FramerateMode FramerateMode { get; set; } + + /// + /// Gets or sets Quality. + /// + public double? Quality { get; set; } + + /// + /// Gets or sets VideoBitrate. + /// + public int? VideoBitrate { get; set; } + + /// + /// Gets or sets a value indicating whether TwoPass. + /// + public bool TwoPass { get; set; } + + /// + /// Gets or sets a value indicating whether TurboFirstPass. + /// + public bool TurboFirstPass { get; set; } + + /// + /// Gets or sets Framerate. + /// Null = Same as Source + /// + public double? Framerate { get; set; } + + #endregion + + #region Audio + + /// + /// Gets or sets AudioEncodings. + /// + public ObservableCollection AudioTracks { get; set; } + + /// + /// Gets or sets AllowedPassthruOptions. + /// + public AllowedPassthru AllowedPassthruOptions { get; set; } + + #endregion + + #region Subtitles + + /// + /// Gets or sets SubtitleTracks. + /// + public ObservableCollection SubtitleTracks { get; set; } + + #endregion + + #region Chapters + + /// + /// Gets or sets a value indicating whether IncludeChapterMarkers. + /// + public bool IncludeChapterMarkers { get; set; } + + /// + /// Gets or sets ChapterMarkersFilePath. + /// + public string ChapterMarkersFilePath { get; set; } + + /// + /// Gets or sets ChapterNames. + /// + public ObservableCollection ChapterNames { get; set; } + + #endregion + + #region Advanced + + /// + /// Gets or sets AdvancedEncoderOptions. + /// + public string AdvancedEncoderOptions { get; set; } + + /// + /// Gets or sets the video profile. + /// + public VideoProfile VideoProfile { get; set; } + + /// + /// Gets or sets the video level. + /// + public VideoLevel VideoLevel { get; set; } + + /// + /// Gets or sets the video preset. + /// + public VideoPreset VideoPreset { get; set; } + + /// + /// Gets or sets the video tunes. + /// + public List VideoTunes { get; set; } + + /// + /// Gets or sets Extra Advanced Arguments for the Video Tab. + /// + public string ExtraAdvancedArguments { get; set; } + + #endregion + + #region Preview + + /// + /// Gets or sets a value indicating whether IsPreviewEncode. + /// + public bool IsPreviewEncode { get; set; } + + /// + /// Gets or sets PreviewEncodeDuration. + /// + public int? PreviewEncodeDuration { get; set; } + + /// + /// Gets or sets PreviewEncodeStartAt. + /// + public int? PreviewEncodeStartAt { get; set; } + + #endregion + + #region Helpers + + /// + /// Gets a value indicating whether M4v extension is required. + /// + public bool RequiresM4v + { + get + { + if (this.OutputFormat == OutputFormat.Mp4) + { + bool audio = + this.AudioTracks.Any( + item => + item.Encoder == AudioEncoder.Ac3Passthrough || item.Encoder == AudioEncoder.Ac3 + || item.Encoder == AudioEncoder.DtsPassthrough || item.Encoder == AudioEncoder.Passthrough); + + bool subtitles = this.SubtitleTracks.Any(track => track.SubtitleType != SubtitleType.VobSub); + + return audio || subtitles; + } + + return false; + } + } + + /// + /// Gets or sets a value indicating whether advanced panel enabled. + /// + public bool ShowAdvancedTab + { + get + { + return this.showAdvancedTab; + } + set + { + if (!Equals(value, this.showAdvancedTab)) + { + this.showAdvancedTab = value; + this.NotifyOfPropertyChange(() => this.ShowAdvancedTab); + } + } + } + + /// + /// Gets the picture settings desc. + /// + public string PictureSettingsDesc + { + get + { + string resolution = string.Empty; + switch (this.Anamorphic) + { + case Anamorphic.Strict: + resolution = "Anamorphic: Strict"; + break; + case Anamorphic.Loose: + resolution = "Anamorphic: Loose, Width: " + this.Width; + break; + case Anamorphic.Custom: + resolution = "Anamorphic: Custom, Resolution: " + this.Width + "x" + this.Height; + break; + case Anamorphic.None: + resolution = "Resolution: " + this.Width + "x" + this.Height; + break; + } + + return resolution + Environment.NewLine + "Crop Top: " + this.Cropping.Top + ", Botton: " + this.Cropping.Bottom + ", Left: " + + this.Cropping.Left + ", Right: " + this.Cropping.Right; + } + } + + #endregion + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AllowedPassthru.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AllowedPassthru.cs new file mode 100644 index 000000000..9586e1632 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AllowedPassthru.cs @@ -0,0 +1,172 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Allowed Passthru Options +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models +{ + using System.Collections.Generic; + + /// + /// Allowed Passthru Options + /// + public class AllowedPassthru + { + #region Constructors and Destructors + + /// + /// Initializes a new instance of the class. + /// + public AllowedPassthru() + { + this.AudioAllowAACPass = true; + this.AudioAllowAC3Pass = true; + this.AudioAllowDTSHDPass = true; + this.AudioAllowDTSPass = true; + this.AudioAllowMP3Pass = true; + this.AudioAllowEAC3Pass = true; + this.AudioAllowTrueHDPass = true; + this.AudioAllowFlacPass = true; + this.AudioEncoderFallback = AudioEncoder.Ac3; + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// The initial Value. + /// + public AllowedPassthru(bool initialValue) + { + this.AudioAllowAACPass = initialValue; + this.AudioAllowAC3Pass = initialValue; + this.AudioAllowDTSHDPass = initialValue; + this.AudioAllowDTSPass = initialValue; + this.AudioAllowMP3Pass = initialValue; + this.AudioAllowEAC3Pass = initialValue; + this.AudioAllowTrueHDPass = initialValue; + this.AudioAllowFlacPass = initialValue; + this.AudioEncoderFallback = AudioEncoder.Ac3; + } + + /// + /// Initializes a new instance of the class. + /// Copy Constructor + /// + /// + /// The initial value. + /// + public AllowedPassthru(AllowedPassthru initialValue) + { + this.AudioAllowAACPass = initialValue.AudioAllowAACPass; + this.AudioAllowAC3Pass = initialValue.AudioAllowAC3Pass; + this.AudioAllowDTSHDPass = initialValue.AudioAllowDTSHDPass; + this.AudioAllowDTSPass = initialValue.AudioAllowDTSPass; + this.AudioAllowMP3Pass = initialValue.AudioAllowMP3Pass; + this.AudioAllowEAC3Pass = initialValue.AudioAllowEAC3Pass; + this.AudioAllowTrueHDPass = initialValue.AudioAllowTrueHDPass; + this.AudioAllowFlacPass = initialValue.AudioAllowFlacPass; + this.AudioEncoderFallback = initialValue.AudioEncoderFallback; + } + + #endregion + + #region Properties + + /// + /// Gets or sets a value indicating whether AudioAllowAACPass. + /// + public bool AudioAllowAACPass { get; set; } + + /// + /// Gets or sets a value indicating whether AudioAllowAC3Pass. + /// + public bool AudioAllowAC3Pass { get; set; } + + /// + /// Gets or sets a value indicating whether AudioAllowDTSHDPass. + /// + public bool AudioAllowDTSHDPass { get; set; } + + /// + /// Gets or sets a value indicating whether AudioAllowDTSPass. + /// + public bool AudioAllowDTSPass { get; set; } + + /// + /// Gets or sets a value indicating whether AudioAllowMP3Pass. + /// + public bool AudioAllowMP3Pass { get; set; } + + /// + /// Gets or sets a value indicating whether audio allow true hd pass. + /// + public bool AudioAllowTrueHDPass { get; set; } + + /// + /// Gets or sets a value indicating whether audio allow flac pass. + /// + public bool AudioAllowFlacPass { get; set; } + + /// + /// Gets or sets a value indicating whether audio allow ea c 3 pass. + /// + public bool AudioAllowEAC3Pass { get; set; } + + /// + /// Gets or sets AudioEncoderFallback. + /// + public AudioEncoder AudioEncoderFallback { get; set; } + + /// + /// Gets the allowed passthru options. + /// + public IEnumerable AllowedPassthruOptions + { + get + { + List audioEncoders = new List(); + if (this.AudioAllowAACPass) + { + audioEncoders.Add(AudioEncoder.AacPassthru); + } + if (this.AudioAllowAC3Pass) + { + audioEncoders.Add(AudioEncoder.Ac3Passthrough); + } + if (this.AudioAllowDTSHDPass) + { + audioEncoders.Add(AudioEncoder.DtsHDPassthrough); + } + if (this.AudioAllowDTSPass) + { + audioEncoders.Add(AudioEncoder.DtsPassthrough); + } + if (this.AudioAllowMP3Pass) + { + audioEncoders.Add(AudioEncoder.Mp3Passthru); + } + if (this.AudioAllowTrueHDPass) + { + audioEncoders.Add(AudioEncoder.TrueHDPassthrough); + } + if (this.AudioAllowFlacPass) + { + audioEncoders.Add(AudioEncoder.FlacPassthru); + } + if (this.AudioAllowEAC3Pass) + { + audioEncoders.Add(AudioEncoder.EAc3Passthrough); + } + + return audioEncoders; + } + } + + #endregion + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioEncoder.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioEncoder.cs new file mode 100644 index 000000000..fe56a1e14 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioEncoder.cs @@ -0,0 +1,89 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// The audio encoder enumeration +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models +{ + using System.ComponentModel.DataAnnotations; + + using HandBrake.ApplicationServices.Attributes; + + /// + /// The audio encoder. + /// + public enum AudioEncoder + { + [Display(Name = "AAC (avcodec)")] + [ShortName("av_aac")] + ffaac, + + [Display(Name = "AAC (FDK)")] + [ShortName("fdk_aac")] + fdkaac, + + [Display(Name = "HE-AAC (FDK)")] + [ShortName("fdk_haac")] + fdkheaac, + + [Display(Name = "MP3")] + [ShortName("mp3")] + Lame, + + [Display(Name = "AC3")] + [ShortName("ac3")] + Ac3, + + [Display(Name = "Auto Passthru")] + [ShortName("copy")] + Passthrough, + + [Display(Name = "AC3 Passthru")] + [ShortName("copy:ac3")] + Ac3Passthrough, + + [Display(Name = "E-AC3 Passthru")] + [ShortName("copy:eac3")] + EAc3Passthrough, + + [Display(Name = "DTS Passthru")] + [ShortName("copy:dts")] + DtsPassthrough, + + [Display(Name = "DTS-HD Passthru")] + [ShortName("copy:dtshd")] + DtsHDPassthrough, + + [Display(Name = "TrueHD Passthru")] + [ShortName("copy:truehd")] + TrueHDPassthrough, + + [Display(Name = "AAC Passthru")] + [ShortName("copy:aac")] + AacPassthru, + + [Display(Name = "MP3 Passthru")] + [ShortName("copy:mp3")] + Mp3Passthru, + + [Display(Name = "Vorbis")] + [ShortName("vorbis")] + Vorbis, + + [Display(Name = "FLAC 16-bit")] + [ShortName("flac16")] + ffflac, + + [Display(Name = "FLAC 24-bit")] + [ShortName("flac24")] + ffflac24, + + [Display(Name = "FLAC Passthru")] + [ShortName("copy:flac")] + FlacPassthru, + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioEncoderRateType.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioEncoderRateType.cs new file mode 100644 index 000000000..d1cd21e5b --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioEncoderRateType.cs @@ -0,0 +1,31 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// The audio encoder rate type. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models +{ + using System.ComponentModel.DataAnnotations; + + /// + /// The audio encoder rate type. + /// + public enum AudioEncoderRateType + { + /// + /// The bitrate. + /// + [Display(Name = "Bitrate: ")] + Bitrate, + + /// + /// The quality. + /// + [Display(Name = "Quality: ")] + Quality, + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioTrack.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioTrack.cs new file mode 100644 index 000000000..c435e88ec --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioTrack.cs @@ -0,0 +1,636 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Model of a HandBrake Audio Track and it's associated behaviours. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models +{ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Globalization; + using System.Linq; + + using HandBrake.ApplicationServices.Interop; + using HandBrake.ApplicationServices.Interop.Model; + using HandBrake.ApplicationServices.Interop.Model.Encoding; + using HandBrake.ApplicationServices.Utilities; + + using HandBrakeWPF.Services.Scan.Model; + + using Newtonsoft.Json; + + /// + /// Model of a HandBrake Audio Track and it's associated behaviours. + /// + public class AudioTrack : PropertyChangedBase + { + private int bitrate; + private double drc; + private HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder encoder; + private int gain; + private Mixdown mixDown; + private double sampleRate; + [NonSerialized] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + private Audio scannedTrack; + private bool isDefault; + private IEnumerable bitrates; + private IEnumerable encoderQualityValues; + private HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType encoderRateType; + private double? quality; + + /// + /// Initializes a new instance of the class. + /// + public AudioTrack() + { + // Default Values + this.Encoder = HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.ffaac; + this.MixDown = Mixdown.DolbyProLogicII; + this.SampleRate = 48; + this.Bitrate = 160; + this.DRC = 0; + this.ScannedTrack = new Audio(); + this.TrackName = string.Empty; + + // Setup Backing Properties + this.EncoderRateType = HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType.Bitrate; + this.SetupLimits(); + } + + /// + /// Initializes a new instance of the class. + /// Copy Constructor + /// + /// + /// The track. + /// + /// + /// The set Scanned Track. + /// + public AudioTrack(AudioTrack track, bool setScannedTrack) + { + this.bitrate = track.Bitrate; + this.drc = track.DRC; + this.encoder = track.Encoder; + this.gain = track.Gain; + this.mixDown = track.MixDown; + this.sampleRate = track.SampleRate; + if (setScannedTrack) + { + this.scannedTrack = track.ScannedTrack ?? new Audio(); + } + this.TrackName = track.TrackName; + this.Quality = track.Quality; + + // Setup Backing Properties + this.encoderRateType = track.EncoderRateType; + this.SetupLimits(); + } + + #region Track Properties + + /// + /// Gets or sets Dynamic Range Compression + /// + public double DRC + { + get + { + return this.drc; + } + + set + { + if (!Equals(value, this.drc)) + { + this.drc = value; + this.NotifyOfPropertyChange(() => this.DRC); + } + } + } + + /// + /// Gets or sets the Gain for the audio track + /// + public int Gain + { + get + { + return this.gain; + } + + set + { + if (!Equals(value, this.gain)) + { + this.gain = value; + this.NotifyOfPropertyChange(() => this.Gain); + } + } + } + + /// + /// Gets or sets Audio Mixdown + /// + public Mixdown MixDown + { + get + { + return this.mixDown; + } + + set + { + this.mixDown = value; + this.NotifyOfPropertyChange(() => this.MixDown); + this.SetupLimits(); + this.NotifyOfPropertyChange(() => this.TrackReference); + } + } + + /// + /// Gets or sets Audio Encoder + /// + public HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder Encoder + { + get + { + return this.encoder; + } + + set + { + this.encoder = value; + this.NotifyOfPropertyChange(() => this.Encoder); + this.NotifyOfPropertyChange(() => this.IsPassthru); + this.NotifyOfPropertyChange(() => this.IsBitrateVisible); + this.NotifyOfPropertyChange(() => this.IsQualityVisible); + this.NotifyOfPropertyChange(() => this.IsRateTypeVisible); + this.SetupLimits(); + this.NotifyOfPropertyChange(() => this.TrackReference); + + // Refresh the available encoder rate types. + this.NotifyOfPropertyChange(() => this.AudioEncoderRateTypes); + if (!this.AudioEncoderRateTypes.Contains(this.EncoderRateType)) + { + this.EncoderRateType = HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType.Bitrate; // Default to bitrate. + } + } + } + + /// + /// Gets or sets Audio SampleRate + /// + public double SampleRate + { + get + { + return this.sampleRate; + } + + set + { + this.sampleRate = value; + this.NotifyOfPropertyChange(() => this.SampleRate); + this.SetupLimits(); + this.NotifyOfPropertyChange(() => this.TrackReference); + } + } + + /// + /// Gets or sets the encoder rate type. + /// + public HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType EncoderRateType + { + get + { + return this.encoderRateType; + } + + set + { + this.encoderRateType = value; + this.SetupLimits(); + this.NotifyOfPropertyChange(() => this.EncoderRateType); + this.NotifyOfPropertyChange(() => this.IsBitrateVisible); + this.NotifyOfPropertyChange(() => this.IsQualityVisible); + + if (!this.Quality.HasValue) + { + HBAudioEncoder hbAudioEncoder = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper.GetShortName(this.Encoder)); + this.Quality = HandBrakeEncoderHelpers.GetDefaultQuality(hbAudioEncoder); + } + } + } + + /// + /// Gets or sets Audio Bitrate + /// + public int Bitrate + { + get + { + return this.bitrate; + } + + set + { + this.bitrate = value; + this.NotifyOfPropertyChange(() => this.Bitrate); + } + } + + /// + /// Gets or sets Audio quality + /// + public double? Quality + { + get + { + return this.quality; + } + + set + { + this.quality = value; + this.NotifyOfPropertyChange(() => this.quality); + } + } + + /// + /// Gets or sets the track name. + /// + public string TrackName { get; set; } + #endregion + + /// + /// Gets AudioEncoderDisplayValue. + /// + [JsonIgnore] + public string AudioEncoderDisplayValue + { + get + { + return EnumHelper.GetDisplay(this.Encoder); + } + } + + /// + /// Gets AudioMixdownDisplayValue. + /// + [JsonIgnore] + public string AudioMixdownDisplayValue + { + get + { + return EnumHelper.GetDisplay(this.MixDown); + } + } + + /// + /// Gets the The UI display value for bit rate + /// + [JsonIgnore] + public string BitRateDisplayValue + { + get + { + if (this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.Ac3Passthrough || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.DtsPassthrough + || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.DtsHDPassthrough) + { + return "Auto"; + } + + return this.Bitrate.ToString(); + } + } + + /// + /// Gets or sets a value indicating whether is default. + /// TODO - Can this be removed? May have been added as a quick fix for a styling quirk. + /// + [JsonIgnore] + public bool IsDefault + { + get + { + return this.isDefault; + } + set + { + this.isDefault = value; + } + } + + /// + /// Gets or sets the The UI display value for sample rate + /// + [JsonIgnore] + public string SampleRateDisplayValue + { + get + { + return this.SampleRate == 0 ? "Auto" : this.SampleRate.ToString(CultureInfo.InvariantCulture); + } + set + { + // TODO change this to be a converted field + if (string.IsNullOrEmpty(value)) + { + return; + } + + double samplerate; + double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out samplerate); + + this.SampleRate = samplerate; + } + } + + /// + /// Gets or sets the Scanned Audio Tracks + /// + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public Audio ScannedTrack + { + get + { + return this.scannedTrack; + } + + set + { + this.scannedTrack = value; + this.NotifyOfPropertyChange(() => this.ScannedTrack); + } + } + + /// + /// Gets the Audio Track Name + /// + [JsonIgnore] + public int? Track + { + get + { + if (this.ScannedTrack != null) + { + return this.ScannedTrack.TrackNumber; + } + + return null; + } + } + + /// + /// Gets a value indicating whether IsPassthru. + /// + [JsonIgnore] + public bool IsPassthru + { + get + { + if (this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.Ac3Passthrough || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.DtsPassthrough + || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.DtsHDPassthrough || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.AacPassthru + || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.Mp3Passthru || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.Passthrough || + this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.EAc3Passthrough || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.TrueHDPassthrough + || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.FlacPassthru) + { + return true; + } + return false; + } + } + + /// + /// Gets the bitrates. + /// + [JsonIgnore] + public IEnumerable Bitrates + { + get + { + return this.bitrates; + } + } + + /// + /// Gets the quality compression values. + /// + [JsonIgnore] + public IEnumerable EncoderQualityValues + { + get + { + return this.encoderQualityValues; + } + } + + /// + /// Gets the audio encoder rate types. + /// + [JsonIgnore] + public IEnumerable AudioEncoderRateTypes + { + get + { + IList types = EnumHelper.GetEnumList().ToList(); + HBAudioEncoder hbaenc = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper.GetShortName(this.Encoder)); + if (hbaenc == null || !hbaenc.SupportsQuality) + { + types.Remove(HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType.Quality); + } + + return types; + } + } + + /// + /// Gets a value indicating whether can set bitrate. + /// + [JsonIgnore] + public bool IsBitrateVisible + { + get + { + if (this.IsPassthru || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.ffflac || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.ffflac24) + { + return false; + } + + return Equals(this.EncoderRateType, HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType.Bitrate); + } + } + + /// + /// Gets a value indicating whether is quality visible. + /// + [JsonIgnore] + public bool IsQualityVisible + { + get + { + if (this.IsPassthru || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.ffflac || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.ffflac24) + { + return false; + } + + return Equals(this.EncoderRateType, HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType.Quality); + } + } + + /// + /// Gets a value indicating whether is rate type visible. + /// + [JsonIgnore] + public bool IsRateTypeVisible + { + get + { + if (this.IsPassthru || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.ffflac || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.ffflac24) + { + return false; + } + + return true; + } + } + + /// + /// Gets a value indicating whether IsLossless. + /// + [JsonIgnore] + public bool IsLossless + { + get + { + return this.IsPassthru || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.ffflac || this.Encoder == HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder.ffflac24; + } + } + + /// + /// Gets TrackReference. + /// + [JsonIgnore] + public AudioTrack TrackReference + { + get { return this; } + } + + #region Handler Methods + + /// + /// The setup limits. + /// + private void SetupLimits() + { + this.SetupBitrateLimits(); + this.SetupQualityCompressionLimits(); + } + + /// + /// The calculate bitrate limits. + /// + private void SetupBitrateLimits() + { + // Base set of bitrates available. + List audioBitrates = HandBrakeEncoderHelpers.AudioBitrates; + + // Defaults + int max = 256; + int low = 32; + + // Based on the users settings, find the high and low bitrates. + HBAudioEncoder hbaenc = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper.GetShortName(this.Encoder)); + HBRate rate = HandBrakeEncoderHelpers.AudioSampleRates.FirstOrDefault(t => t.Name == this.SampleRate.ToString(CultureInfo.InvariantCulture)); + HBMixdown mixdown = HandBrakeEncoderHelpers.GetMixdown(EnumHelper.GetShortName(this.MixDown)); + + BitrateLimits limits = HandBrakeEncoderHelpers.GetBitrateLimits(hbaenc, rate != null ? rate.Rate : 48000, mixdown); + if (limits != null) + { + max = limits.High; + low = limits.Low; + } + + // Return the subset of available bitrates. + List subsetBitrates = audioBitrates.Where(b => b <= max && b >= low).ToList(); + this.bitrates = subsetBitrates; + this.NotifyOfPropertyChange(() => this.Bitrates); + + // If the subset does not contain the current bitrate, request the default. + if (!subsetBitrates.Contains(this.Bitrate)) + { + this.Bitrate = HandBrakeEncoderHelpers.GetDefaultBitrate(hbaenc, rate != null ? rate.Rate : 48000, mixdown); + } + } + + /// + /// The setup quality compression limits. + /// + private void SetupQualityCompressionLimits() + { + HBAudioEncoder hbAudioEncoder = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper.GetShortName(this.Encoder)); + if (hbAudioEncoder.SupportsQuality) + { + RangeLimits limits = null; + + if (hbAudioEncoder.SupportsQuality) + { + limits = hbAudioEncoder.QualityLimits; + } + + if (limits != null) + { + double value = limits.Ascending ? limits.Low : limits.High; + List values = new List { value }; + + if (limits.Ascending) + { + while (value < limits.High) + { + value += limits.Granularity; + values.Add(value); + } + } + else + { + while (value > limits.Low) + { + value -= limits.Granularity; + values.Add(value); + } + } + + this.encoderQualityValues = values; + } + else + { + this.encoderQualityValues = new List(); + } + } + else + { + this.encoderQualityValues = new List(); + } + + // Default the audio quality value if it's out of range. + if (Equals(this.EncoderRateType, HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType.Quality)) + { + if (this.Quality.HasValue && !this.encoderQualityValues.Contains(this.Quality.Value)) + { + this.Quality = HandBrakeEncoderHelpers.GetDefaultQuality(hbAudioEncoder); + } + } + + this.NotifyOfPropertyChange(() => this.EncoderQualityValues); + } + + #endregion + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/ChapterMarker.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/ChapterMarker.cs new file mode 100644 index 000000000..da6979a4a --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/ChapterMarker.cs @@ -0,0 +1,92 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// A Movie Chapter +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models +{ + using System; + + using HandBrake.ApplicationServices.Utilities; + + /// + /// A Movie Chapter + /// + public class ChapterMarker : PropertyChangedBase + { + /// + /// Backing field for chapter name + /// + private string chapterName; + + /// + /// Initializes a new instance of the class. + /// + public ChapterMarker() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// The number. + /// + /// + /// The name. + /// + /// + /// The duration. + /// + public ChapterMarker(int number, string name, TimeSpan duration) + { + this.ChapterName = name; + this.ChapterNumber = number; + this.Duration = duration; + } + + /// + /// Initializes a new instance of the class. + /// Copy Constructor + /// + /// + /// The chapter. + /// + public ChapterMarker(ChapterMarker chapter) + { + this.ChapterName = chapter.ChapterName; + this.ChapterNumber = chapter.ChapterNumber; + this.Duration = chapter.Duration; + } + + /// + /// Gets or sets The number of this Chapter, in regards to it's parent Title + /// + public int ChapterNumber { get; set; } + + /// + /// Gets or sets the duration. + /// + public TimeSpan Duration { get; set; } + + /// + /// Gets or sets ChapterName. + /// + public string ChapterName + { + get + { + return this.chapterName; + } + set + { + this.chapterName = value; + this.NotifyOfPropertyChange(() => this.ChapterName); + } + } + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/DenoisePreset.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/DenoisePreset.cs new file mode 100644 index 000000000..80ef02d7d --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/DenoisePreset.cs @@ -0,0 +1,45 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Defines the DenoisePreset type. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models +{ + using System.ComponentModel.DataAnnotations; + + using HandBrake.ApplicationServices.Attributes; + + /// + /// The denoise preset. + /// + public enum DenoisePreset + { + [Display(Name = "Weak")] + [ShortName("weak")] + Weak = 0, + + [Display(Name = "Medium")] + [ShortName("medium")] + Medium, + + [Display(Name = "Strong")] + [ShortName("strong")] + Strong, + + [Display(Name = "Custom")] + [ShortName("custom")] + Custom, + + [Display(Name = "Ultralight")] // NLMeans only + [ShortName("ultralight")] + Ultralight, + + [Display(Name = "Light")] // NLMeans only + [ShortName("light")] + Light, + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/DenoiseTune.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/DenoiseTune.cs new file mode 100644 index 000000000..eb006ac3f --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/DenoiseTune.cs @@ -0,0 +1,41 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Defines the DenoiseTune type. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models +{ + using System.ComponentModel.DataAnnotations; + + using HandBrake.ApplicationServices.Attributes; + + /// + /// The denoise tune. + /// + public enum DenoiseTune + { + [Display(Name = "None")] + [ShortName("none")] + None = 0, + + [Display(Name = "Film")] + [ShortName("film")] + Film, + + [Display(Name = "Grain")] + [ShortName("grain")] + Grain, + + [Display(Name = "High Motion")] + [ShortName("highmotion")] + HighMotion, + + [Display(Name = "Animation")] + [ShortName("animation")] + Animation, + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/FramerateMode.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/FramerateMode.cs new file mode 100644 index 000000000..d8eaa20fb --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/FramerateMode.cs @@ -0,0 +1,28 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// The Mode of Video Encoding. CFR, VFR, PFR +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models +{ + using HandBrake.ApplicationServices.Attributes; + + /// + /// The Mode of Video Encoding. CFR, VFR, PFR + /// + public enum FramerateMode + { + [ShortName("cfr")] + CFR = 0, + + [ShortName("pfr")] + PFR, + + [ShortName("vfr")] + VFR + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/OutputFormat.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/OutputFormat.cs new file mode 100644 index 000000000..d7e382b06 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/OutputFormat.cs @@ -0,0 +1,32 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// The Output format. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models +{ + using System.ComponentModel; + using System.ComponentModel.DataAnnotations; + + using HandBrake.ApplicationServices.Attributes; + + /// + /// The Output format. + /// + public enum OutputFormat + { + [Description("MP4")] + [Display(Name = "MP4")] + [ShortName("av_mp4")] + Mp4 = 0, + + [Description("MKV")] + [Display(Name = "MKV")] + [ShortName("av_mkv")] + Mkv, + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/PointToPointMode.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/PointToPointMode.cs new file mode 100644 index 000000000..86f8d0133 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/PointToPointMode.cs @@ -0,0 +1,31 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Point to Point Mode +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models +{ + using System.ComponentModel.DataAnnotations; + + /// + /// Point to Point Mode + /// + public enum PointToPointMode + { + [Display(Name = "Chapters")] + Chapters = 0, + + [Display(Name = "Seconds")] + Seconds, + + [Display(Name = "Frames")] + Frames, + + [Display(Name = "Preview")] + Preview, + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleTrack.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleTrack.cs new file mode 100644 index 000000000..9f2ea9ded --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleTrack.cs @@ -0,0 +1,275 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Subtitle Information +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models +{ + using System; + + using HandBrake.ApplicationServices.Utilities; + + using HandBrakeWPF.Services.Scan.Model; + + /// + /// Subtitle Information + /// + public class SubtitleTrack : PropertyChangedBase + { + #region Constants and Fields + + /// + /// The burned in backing field. + /// + private bool burned; + + /// + /// The is default backing field. + /// + private bool isDefault; + + /// + /// The source track. + /// + private Subtitle sourceTrack; + + /// + /// Backing field for the srt file name. + /// + private string srtFileName; + + /// + /// Backing field for Forced Subs + /// + private bool forced; + + #endregion + + #region Constructors and Destructors + + /// + /// Initializes a new instance of the class. + /// + public SubtitleTrack() + { + } + + /// + /// Initializes a new instance of the class. + /// Copy Constructor + /// + /// + /// The subtitle. + /// + public SubtitleTrack(SubtitleTrack subtitle) + { + this.Burned = subtitle.Burned; + this.Default = subtitle.Default; + this.Forced = subtitle.Forced; + this.sourceTrack = subtitle.SourceTrack; + this.SrtCharCode = subtitle.SrtCharCode; + this.SrtFileName = subtitle.SrtFileName; + this.SrtLang = subtitle.SrtLang; + this.SrtOffset = subtitle.SrtOffset; + this.SrtPath = subtitle.SrtPath; + this.SubtitleType = subtitle.SubtitleType; + this.SourceTrack = subtitle.SourceTrack; + } + + #endregion + + #region Properties + + /// + /// Gets or sets a value indicating whether Burned. + /// + public bool Burned + { + get + { + return this.burned; + } + + set + { + if (!Equals(this.burned, value)) + { + this.burned = value; + this.NotifyOfPropertyChange(() => this.Burned); + + if (value) + { + this.Default = false; + } + } + } + } + + /// + /// Gets or sets a value indicating whether Default. + /// + public bool Default + { + get + { + return this.isDefault; + } + + set + { + if (!Equals(this.isDefault, value)) + { + this.isDefault = value; + this.NotifyOfPropertyChange(() => this.Default); + + if (value) + { + this.Burned = false; + } + } + } + } + + /// + /// Gets or sets a value indicating whether Forced. + /// + public bool Forced + { + get + { + return this.forced; + } + set + { + this.forced = value; + this.NotifyOfPropertyChange(() => this.Forced); + } + } + + /// + /// Gets or sets SourceTrack. + /// + public Subtitle SourceTrack + { + get + { + return this.sourceTrack; + } + + set + { + this.sourceTrack = value; + this.NotifyOfPropertyChange(() => this.SourceTrack); + if (this.sourceTrack != null) + { + this.Track = this.sourceTrack.ToString(); + } + + this.NotifyOfPropertyChange(() => this.CanBeBurned); + this.NotifyOfPropertyChange(() => this.CanBeForced); + } + } + + /// + /// Gets or sets the SRT Character Code + /// + public string SrtCharCode { get; set; } + + /// + /// Gets or sets the SRT Filename + /// + public string SrtFileName + { + get + { + return this.srtFileName; + } + + set + { + this.srtFileName = value; + this.NotifyOfPropertyChange(() => this.IsSrtSubtitle); + } + } + + /// + /// Gets or sets the SRT Language + /// + public string SrtLang { get; set; } + + /// + /// Gets or sets the SRT Offset + /// + public int SrtOffset { get; set; } + + /// + /// Gets or sets the Path to the SRT file + /// + public string SrtPath { get; set; } + + /// + /// Gets or sets the type of the subtitle + /// + public SubtitleType SubtitleType { get; set; } + + /// + /// Gets or sets Track. + /// + [Obsolete("Use SourceTrack Instead")] + public string Track { get; set; } + + #endregion + + /// + /// Gets a value indicating whether CanForced. + /// + public bool CanBeForced + { + get + { + if (this.SourceTrack != null) + { + return this.SourceTrack.CanForce || this.SourceTrack.SubtitleType == SubtitleType.ForeignAudioSearch; + } + + return false; + } + } + + /// + /// Gets a value indicating whether CanBeBurned. + /// + public bool CanBeBurned + { + get + { + if (this.SourceTrack != null) + { + return this.SourceTrack.CanBurnIn || this.SourceTrack.SubtitleType == SubtitleType.ForeignAudioSearch || this.SubtitleType == SubtitleType.SRT; + } + + if (this.SubtitleType == SubtitleType.SRT) + { + return true; + } + + return false; + } + } + + /// + /// Gets a value indicating whether this is an SRT subtitle. + /// + public bool IsSrtSubtitle + { + get + { + return this.SrtFileName != "-" && this.SrtFileName != null; + } + } + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleType.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleType.cs new file mode 100644 index 000000000..85f9bf473 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleType.cs @@ -0,0 +1,38 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Subtitle Type. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models +{ + using System.ComponentModel; + + /// + /// Subtitle Type. + /// + public enum SubtitleType + { + [Description("SSA")] + SSA, + [Description("SRT")] + SRT, + [Description("VobSub")] + VobSub, + [Description("CC")] + CC, + [Description("UTF8")] + UTF8Sub, + [Description("TX3G")] + TX3G, + [Description("PGS")] + PGS, + [Description("Unknown")] + Unknown, + [Description("Foreign Audio Search")] + ForeignAudioSearch, // Special Type for Foreign Audio Search + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoLevel.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoLevel.cs new file mode 100644 index 000000000..e7ca53e06 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoLevel.cs @@ -0,0 +1,118 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// The video level. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models.Video +{ + using VideoLevelFactory = HandBrakeWPF.Services.Encode.Factories.VideoLevelFactory; + + /// + /// The video level. + /// + public class VideoLevel + { + /// + /// An internal representation of the Auto Selection. + /// + public static VideoLevel Auto = new VideoLevel("Auto", "auto"); + + /// + /// Initializes a new instance of the class. + /// + public VideoLevel() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// The display name. + /// + /// + /// The short name. + /// + public VideoLevel(string displayName, string shortName) + { + this.DisplayName = VideoLevelFactory.GetDisplayName(displayName); + this.ShortName = shortName; + } + + /// + /// Gets or sets the display name. + /// + public string DisplayName { get; set; } + + /// + /// Gets or sets the short name. + /// + public string ShortName { get; set; } + + /// + /// The clone. + /// + /// + /// The . + /// + public VideoLevel Clone() + { + return new VideoLevel(this.DisplayName, this.ShortName); + } + + /// + /// The equals. + /// + /// + /// The other. + /// + /// + /// The . + /// + protected bool Equals(VideoLevel other) + { + return string.Equals(this.ShortName, other.ShortName); + } + + /// + /// The equals. + /// + /// + /// The obj. + /// + /// + /// The . + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + if (ReferenceEquals(this, obj)) + { + return true; + } + if (obj.GetType() != this.GetType()) + { + return false; + } + return this.Equals((VideoLevel)obj); + } + + /// + /// The get hash code. + /// + /// + /// The . + /// + public override int GetHashCode() + { + return (this.ShortName != null ? this.ShortName.GetHashCode() : 0); + } + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoPreset.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoPreset.cs new file mode 100644 index 000000000..8efdf5b58 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoPreset.cs @@ -0,0 +1,121 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// The video preset. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models.Video +{ + using VideoPresetFactory = HandBrakeWPF.Services.Encode.Factories.VideoPresetFactory; + + /// + /// The video preset. + /// + public class VideoPreset + { + /// + /// A built-in version of the "None" object. + /// + public static VideoPreset None = new VideoPreset("None", "none"); + + /// + /// Initializes a new instance of the class. + /// + public VideoPreset() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// The display name. + /// + /// + /// The short name. + /// + public VideoPreset(string displayName, string shortName) + { + this.DisplayName = VideoPresetFactory.GetDisplayName(displayName); + this.ShortName = shortName; + } + + /// + /// Gets or sets the display name. + /// + public string DisplayName { get; set; } + + /// + /// Gets or sets the short name. + /// + public string ShortName { get; set; } + + /// + /// The clone. + /// + /// + /// The . + /// + public VideoPreset Clone() + { + return new VideoPreset(this.DisplayName, this.ShortName); + } + + /// + /// The equals. + /// + /// + /// The other. + /// + /// + /// The . + /// + protected bool Equals(VideoPreset other) + { + return string.Equals(this.ShortName, other.ShortName); + } + + /// + /// The equals. + /// + /// + /// The obj. + /// + /// + /// The . + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != this.GetType()) + { + return false; + } + + return this.Equals((VideoPreset)obj); + } + + /// + /// The get hash code. + /// + /// + /// The . + /// + public override int GetHashCode() + { + return (this.ShortName != null ? this.ShortName.GetHashCode() : 0); + } + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoProfile.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoProfile.cs new file mode 100644 index 000000000..80d3fe26d --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoProfile.cs @@ -0,0 +1,121 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// The video profile. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models.Video +{ + using VideoProfileFactory = HandBrakeWPF.Services.Encode.Factories.VideoProfileFactory; + + /// + /// The video profile. + /// + public class VideoProfile + { + /// + /// An internal representation of the Auto Selection. + /// + public static VideoProfile Auto = new VideoProfile("Auto", "auto"); + + /// + /// Initializes a new instance of the class. + /// + public VideoProfile() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// The display name. + /// + /// + /// The short name. + /// + public VideoProfile(string displayName, string shortName) + { + this.DisplayName = VideoProfileFactory.GetDisplayName(displayName); + this.ShortName = shortName; + } + + /// + /// Gets or sets the display name. + /// + public string DisplayName { get; set; } + + /// + /// Gets or sets the short name. + /// + public string ShortName { get; set; } + + /// + /// The clone. + /// + /// + /// The . + /// + public VideoProfile Clone() + { + return new VideoProfile(this.DisplayName, this.ShortName); + } + + /// + /// The equals. + /// + /// + /// The other. + /// + /// + /// The . + /// + protected bool Equals(VideoProfile other) + { + return string.Equals(this.DisplayName, other.DisplayName) && string.Equals(this.ShortName, other.ShortName); + } + + /// + /// The equals. + /// + /// + /// The obj. + /// + /// + /// The . + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + if (ReferenceEquals(this, obj)) + { + return true; + } + if (obj.GetType() != this.GetType()) + { + return false; + } + return this.Equals((VideoProfile)obj); + } + + /// + /// The get hash code. + /// + /// + /// The . + /// + public override int GetHashCode() + { + unchecked + { + return ((this.DisplayName != null ? this.DisplayName.GetHashCode() : 0) * 397) ^ (this.ShortName != null ? this.ShortName.GetHashCode() : 0); + } + } + } +} diff --git a/win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoTune.cs b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoTune.cs new file mode 100644 index 000000000..deba2a56f --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoTune.cs @@ -0,0 +1,137 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// The video tune. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Encode.Model.Models.Video +{ + using VideoTuneFactory = HandBrakeWPF.Services.Encode.Factories.VideoTuneFactory; + + /// + /// The video tune. + /// + public class VideoTune + { + /// + /// Static object to represent "None" + /// + public static VideoTune None = new VideoTune("None", "none"); + + /// + /// Static object to represent "None" + /// + public static VideoTune FastDecode = new VideoTune("Fast Decode", "fastdecode"); + + /// + /// Initializes a new instance of the class. + /// + public VideoTune() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// + /// The display name. + /// + /// + /// The short name. + /// + public VideoTune(string displayName, string shortName) + { + this.DisplayName = VideoTuneFactory.GetDisplayName(displayName); + this.ShortName = shortName; + } + + /// + /// Gets or sets the display name. + /// + public string DisplayName { get; set; } + + /// + /// Gets or sets the short name. + /// + public string ShortName { get; set; } + + /// + /// The clone. + /// + /// + /// The . + /// + public VideoTune Clone() + { + return new VideoTune(this.DisplayName, this.ShortName); + } + + /// + /// The equals. + /// + /// + /// The other. + /// + /// + /// The . + /// + protected bool Equals(HandBrakeWPF.Services.Encode.Model.Models.Video.VideoProfile other) + { + return string.Equals(this.DisplayName, other.DisplayName) && string.Equals(this.ShortName, other.ShortName); + } + + /// + /// The equals. + /// + /// + /// The other. + /// + /// + /// The . + /// + protected bool Equals(VideoTune other) + { + return string.Equals(this.ShortName, other.ShortName); + } + + /// + /// The equals. + /// + /// + /// The obj. + /// + /// + /// The . + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + if (ReferenceEquals(this, obj)) + { + return true; + } + if (obj.GetType() != this.GetType()) + { + return false; + } + return this.Equals((VideoTune)obj); + } + + /// + /// The get hash code. + /// + /// + /// The . + /// + public override int GetHashCode() + { + return (this.ShortName != null ? this.ShortName.GetHashCode() : 0); + } + } +} diff --git a/win/CS/HandBrakeWPF/Services/PrePostActionService.cs b/win/CS/HandBrakeWPF/Services/PrePostActionService.cs index 45889207f..1d54d1e6f 100644 --- a/win/CS/HandBrakeWPF/Services/PrePostActionService.cs +++ b/win/CS/HandBrakeWPF/Services/PrePostActionService.cs @@ -15,7 +15,6 @@ namespace HandBrakeWPF.Services using Caliburn.Micro; - using HandBrake.ApplicationServices.Services.Encode.EventArgs; using HandBrake.ApplicationServices.Utilities; using HandBrakeWPF.EventArgs; @@ -23,6 +22,7 @@ namespace HandBrakeWPF.Services using HandBrakeWPF.Services.Queue.Interfaces; using HandBrakeWPF.ViewModels.Interfaces; + using EncodeCompletedEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs; using Execute = Caliburn.Micro.Execute; /// diff --git a/win/CS/HandBrakeWPF/Services/Presets/Factories/JsonPresetFactory.cs b/win/CS/HandBrakeWPF/Services/Presets/Factories/JsonPresetFactory.cs index 7b50cb750..4be9cc038 100644 --- a/win/CS/HandBrakeWPF/Services/Presets/Factories/JsonPresetFactory.cs +++ b/win/CS/HandBrakeWPF/Services/Presets/Factories/JsonPresetFactory.cs @@ -18,9 +18,6 @@ namespace HandBrakeWPF.Services.Presets.Factories using HandBrake.ApplicationServices.Interop.Model; using HandBrake.ApplicationServices.Interop.Model.Encoding; using HandBrake.ApplicationServices.Model; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; - using HandBrake.ApplicationServices.Services.Encode.Model.Models.Video; using HandBrake.ApplicationServices.Utilities; using HandBrakeWPF.Model.Audio; @@ -28,6 +25,18 @@ namespace HandBrakeWPF.Services.Presets.Factories using HandBrakeWPF.Model.Subtitles; using HandBrakeWPF.Services.Presets.Model; + using AudioEncoder = HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder; + using AudioTrack = HandBrakeWPF.Services.Encode.Model.Models.AudioTrack; + using DenoisePreset = HandBrakeWPF.Services.Encode.Model.Models.DenoisePreset; + using DenoiseTune = HandBrakeWPF.Services.Encode.Model.Models.DenoiseTune; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + using FramerateMode = HandBrakeWPF.Services.Encode.Model.Models.FramerateMode; + using OutputFormat = HandBrakeWPF.Services.Encode.Model.Models.OutputFormat; + using VideoLevel = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoLevel; + using VideoPreset = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoPreset; + using VideoProfile = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoProfile; + using VideoTune = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoTune; + /// /// The json preset factory. /// diff --git a/win/CS/HandBrakeWPF/Services/Presets/Model/Preset.cs b/win/CS/HandBrakeWPF/Services/Presets/Model/Preset.cs index 92aa27092..113e02e38 100644 --- a/win/CS/HandBrakeWPF/Services/Presets/Model/Preset.cs +++ b/win/CS/HandBrakeWPF/Services/Presets/Model/Preset.cs @@ -9,13 +9,10 @@ namespace HandBrakeWPF.Services.Presets.Model { - using Caliburn.Micro; - - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrakeWPF.Model.Audio; using HandBrakeWPF.Model.Subtitles; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; using PresetPictureSettingsMode = HandBrakeWPF.Model.Picture.PresetPictureSettingsMode; /// diff --git a/win/CS/HandBrakeWPF/Services/Presets/PresetService.cs b/win/CS/HandBrakeWPF/Services/Presets/PresetService.cs index 9e1cba6ad..ce666f8aa 100644 --- a/win/CS/HandBrakeWPF/Services/Presets/PresetService.cs +++ b/win/CS/HandBrakeWPF/Services/Presets/PresetService.cs @@ -21,15 +21,12 @@ namespace HandBrakeWPF.Services.Presets using HandBrake.ApplicationServices.Exceptions; using HandBrake.ApplicationServices.Interop; using HandBrake.ApplicationServices.Interop.Json.Presets; - using HandBrake.ApplicationServices.Interop.Model.Encoding; using HandBrake.ApplicationServices.Model; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; using HandBrake.ApplicationServices.Utilities; - using HandBrakeWPF.Model.Audio; using HandBrakeWPF.Model.Picture; - using HandBrakeWPF.Model.Subtitles; using HandBrakeWPF.Properties; + using HandBrakeWPF.Services.Encode.Model.Models; using HandBrakeWPF.Services.Interfaces; using HandBrakeWPF.Services.Presets.Factories; using HandBrakeWPF.Services.Presets.Interfaces; diff --git a/win/CS/HandBrakeWPF/Services/Queue/Interfaces/IQueueProcessor.cs b/win/CS/HandBrakeWPF/Services/Queue/Interfaces/IQueueProcessor.cs index aaeb37708..7a27f685f 100644 --- a/win/CS/HandBrakeWPF/Services/Queue/Interfaces/IQueueProcessor.cs +++ b/win/CS/HandBrakeWPF/Services/Queue/Interfaces/IQueueProcessor.cs @@ -12,10 +12,10 @@ namespace HandBrakeWPF.Services.Queue.Interfaces using System; using System.ComponentModel; - using HandBrake.ApplicationServices.Services.Encode.Interfaces; - using HandBrakeWPF.Services.Queue.Model; + using IEncode = HandBrakeWPF.Services.Encode.Interfaces.IEncode; + /// /// The Queue Processor /// diff --git a/win/CS/HandBrakeWPF/Services/Queue/Model/QueueTask.cs b/win/CS/HandBrakeWPF/Services/Queue/Model/QueueTask.cs index f11cb9b8d..79de64c24 100644 --- a/win/CS/HandBrakeWPF/Services/Queue/Model/QueueTask.cs +++ b/win/CS/HandBrakeWPF/Services/Queue/Model/QueueTask.cs @@ -10,9 +10,10 @@ namespace HandBrakeWPF.Services.Queue.Model { using HandBrake.ApplicationServices.Model; - using HandBrake.ApplicationServices.Services.Encode.Model; using HandBrake.ApplicationServices.Utilities; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + /// /// The QueueTask. /// diff --git a/win/CS/HandBrakeWPF/Services/Queue/QueueProcessor.cs b/win/CS/HandBrakeWPF/Services/Queue/QueueProcessor.cs index 15e05347b..4056633bb 100644 --- a/win/CS/HandBrakeWPF/Services/Queue/QueueProcessor.cs +++ b/win/CS/HandBrakeWPF/Services/Queue/QueueProcessor.cs @@ -18,13 +18,13 @@ namespace HandBrakeWPF.Services.Queue using HandBrake.ApplicationServices.Exceptions; using HandBrake.ApplicationServices.Model; - using HandBrake.ApplicationServices.Services.Encode.EventArgs; - using HandBrake.ApplicationServices.Services.Encode.Interfaces; using HandBrake.ApplicationServices.Utilities; using HandBrakeWPF.Services.Queue.Model; + using EncodeCompletedEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs; using Execute = Caliburn.Micro.Execute; + using IEncode = HandBrakeWPF.Services.Encode.Interfaces.IEncode; using QueueCompletedEventArgs = HandBrakeWPF.EventArgs.QueueCompletedEventArgs; using QueueProgressEventArgs = HandBrakeWPF.EventArgs.QueueProgressEventArgs; diff --git a/win/CS/HandBrakeWPF/Services/Scan/EventArgs/ScanCompletedEventArgs.cs b/win/CS/HandBrakeWPF/Services/Scan/EventArgs/ScanCompletedEventArgs.cs new file mode 100644 index 000000000..75520fef6 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Scan/EventArgs/ScanCompletedEventArgs.cs @@ -0,0 +1,70 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Scan Progress Event Args +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Scan.EventArgs +{ + using System; + + using HandBrakeWPF.Services.Scan.Model; + + /// + /// Scan Progress Event Args + /// + public class ScanCompletedEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// + /// Whether the scan was cancelled. + /// + /// + /// The exception. + /// + /// + /// The error information. + /// + /// + /// The scanned Source. + /// + public ScanCompletedEventArgs(bool cancelled, Exception exception, string errorInformation, Source scannedSource) + { + this.Successful = !cancelled && exception == null && string.IsNullOrEmpty(errorInformation) && scannedSource != null && scannedSource.Titles != null && scannedSource.Titles.Count > 0; + this.Cancelled = cancelled; + this.Exception = exception; + this.ErrorInformation = errorInformation; + this.ScannedSource = scannedSource; + } + + /// + /// Gets a value indicating whether Successful. + /// + public bool Successful { get; private set; } + + /// + /// Gets a value indicating whether Cancelled. + /// + public bool Cancelled { get; private set; } + + /// + /// Gets the Exception. + /// + public Exception Exception { get; private set; } + + /// + /// Gets ErrorInformation. + /// + public string ErrorInformation { get; private set; } + + /// + /// Gets the scanned source. + /// + public Source ScannedSource { get; private set; } + } +} diff --git a/win/CS/HandBrakeWPF/Services/Scan/EventArgs/ScanProgressEventArgs.cs b/win/CS/HandBrakeWPF/Services/Scan/EventArgs/ScanProgressEventArgs.cs new file mode 100644 index 000000000..8d815b746 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Scan/EventArgs/ScanProgressEventArgs.cs @@ -0,0 +1,39 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Scan Progress Event Args +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Scan.EventArgs +{ + using System; + using System.Runtime.Serialization; + + /// + /// Scan Progress Event Args + /// + [DataContract] + public class ScanProgressEventArgs : EventArgs + { + /// + /// Gets or sets the title currently being scanned. + /// + [DataMember] + public int CurrentTitle { get; set; } + + /// + /// Gets or sets the total number of Titles. + /// + [DataMember] + public int Titles { get; set; } + + /// + /// Gets or sets the percentage. + /// + [DataMember] + public decimal Percentage { get; set; } + } +} diff --git a/win/CS/HandBrakeWPF/Services/Scan/Interfaces/IScan.cs b/win/CS/HandBrakeWPF/Services/Scan/Interfaces/IScan.cs new file mode 100644 index 000000000..1c0d3a851 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Scan/Interfaces/IScan.cs @@ -0,0 +1,113 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Encode Progess Status +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Scan.Interfaces +{ + using System; + using System.Windows.Media.Imaging; + + using HandBrake.ApplicationServices.Model; + + using HandBrakeWPF.Services.Encode.Model; + using HandBrakeWPF.Services.Scan.EventArgs; + using HandBrakeWPF.Services.Scan.Model; + + /// + /// Encode Progess Status + /// + /// + /// The sender. + /// + /// + /// The EncodeProgressEventArgs. + /// + public delegate void ScanProgessStatus(object sender, ScanProgressEventArgs e); + + /// + /// Encode Progess Status + /// + /// + /// The sender. + /// + /// + /// The ScanCompletedEventArgs. + /// + public delegate void ScanCompletedStatus(object sender, ScanCompletedEventArgs e); + + /// + /// The IScan Interface + /// + public interface IScan + { + /// + /// Scan has Started + /// + event EventHandler ScanStarted; + + /// + /// Scan has completed + /// + event ScanCompletedStatus ScanCompleted; + + /// + /// Scan process has changed to a new title + /// + event ScanProgessStatus ScanStatusChanged; + + /// + /// Gets a value indicating whether IsScanning. + /// + bool IsScanning { get; } + + /// + /// Gets ActivityLog. + /// + string ActivityLog { get; } + + /// + /// Scan a Source Path. + /// Title 0: scan all + /// + /// + /// Path to the file to scan + /// + /// + /// int title number. 0 for scan all + /// + /// + /// The post Action. + /// + /// + /// The configuraiton. + /// + void Scan(string sourcePath, int title, Action postAction, HBConfiguration configuration); + + /// + /// Get a Preview image for the current job and preview number. + /// + /// + /// The task. + /// + /// + /// The preview. + /// + /// + /// The configuration. + /// + /// + /// The . + /// + BitmapImage GetPreview(EncodeTask task, int preview, HBConfiguration configuration); + + /// + /// Kill the scan + /// + void Stop(); + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/Scan/LibScan.cs b/win/CS/HandBrakeWPF/Services/Scan/LibScan.cs new file mode 100644 index 000000000..2aae331d6 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Scan/LibScan.cs @@ -0,0 +1,600 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Scan a Source +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Scan +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.IO; + using System.Text; + using System.Windows.Media.Imaging; + + using HandBrake.ApplicationServices.Interop; + using HandBrake.ApplicationServices.Interop.EventArgs; + using HandBrake.ApplicationServices.Interop.HbLib; + using HandBrake.ApplicationServices.Interop.Interfaces; + using HandBrake.ApplicationServices.Interop.Json.Scan; + using HandBrake.ApplicationServices.Interop.Model; + using HandBrake.ApplicationServices.Interop.Model.Preview; + using HandBrake.ApplicationServices.Model; + using HandBrake.ApplicationServices.Utilities; + + using HandBrakeWPF.Services.Encode.Model; + using HandBrakeWPF.Services.Encode.Model.Models; + using HandBrakeWPF.Services.Scan.EventArgs; + using HandBrakeWPF.Services.Scan.Interfaces; + using HandBrakeWPF.Services.Scan.Model; + + using Chapter = HandBrakeWPF.Services.Scan.Model.Chapter; + using ScanProgressEventArgs = HandBrake.ApplicationServices.Interop.EventArgs.ScanProgressEventArgs; + using Subtitle = HandBrakeWPF.Services.Scan.Model.Subtitle; + using Title = HandBrakeWPF.Services.Scan.Model.Title; + + /// + /// Scan a Source + /// + public class LibScan : IScan + { + #region Private Variables + + /// + /// Lock for the log file + /// + static readonly object LogLock = new object(); + + /// + /// Log data from HandBrakeInstance + /// + private readonly StringBuilder logging; + + /// + /// The Log File Header + /// + private readonly StringBuilder header; + + /// + /// The Current source scan path. + /// + private string currentSourceScanPath; + + /// + /// The log dir. + /// + private static string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs"; + + /// + /// The dvd info path. + /// + private string dvdInfoPath = Path.Combine(logDir, string.Format("last_scan_log{0}.txt", GeneralUtilities.ProcessId)); + + /// + /// The scan log. + /// + private StreamWriter scanLog; + + /// + /// LibHB Instance + /// + private IHandBrakeInstance instance; + + /// + /// The post scan operation. + /// + private Action postScanOperation; + + #endregion + + /// + /// Initializes a new instance of the class. + /// + public LibScan() + { + this.logging = new StringBuilder(); + this.header = GeneralUtilities.CreateLogHeader(); + this.IsScanning = false; + } + + #region Events + + /// + /// Scan has Started + /// + public event EventHandler ScanStarted; + + /// + /// Scan has completed + /// + public event ScanCompletedStatus ScanCompleted; + + /// + /// Encode process has progressed + /// + public event ScanProgessStatus ScanStatusChanged; + + #endregion + + #region Properties + + /// + /// Gets a value indicating whether IsScanning. + /// + public bool IsScanning { get; private set; } + + /// + /// Gets ActivityLog. + /// + public string ActivityLog + { + get + { + string noLog = "There is no log information to display." + Environment.NewLine + Environment.NewLine + + "This window will only display logging information after you have scanned a source." + Environment.NewLine + + Environment.NewLine + "You can find previous log files in the log directory or by clicking the 'Open Log Directory' button above."; + + return string.IsNullOrEmpty(this.logging.ToString()) ? noLog : this.header + this.logging.ToString(); + } + } + + #endregion + + #region Public Methods + + /// + /// Scan a Source Path. + /// Title 0: scan all + /// + /// + /// Path to the file to scan + /// + /// + /// int title number. 0 for scan all + /// + /// + /// The post Action. + /// + /// + /// The configuraiton. + /// + public void Scan(string sourcePath, int title, Action postAction, HBConfiguration configuraiton) + { + // Try to cleanup any previous scan instances. + if (this.instance != null) + { + try + { + lock (LogLock) + { + this.scanLog.Close(); + this.scanLog.Dispose(); + this.scanLog = null; + } + this.instance.Dispose(); + } + catch (Exception) + { + // Do Nothing + } + } + + // Handle the post scan operation. + this.postScanOperation = postAction; + + // Clear down the logging + this.logging.Clear(); + + try + { + // Make we don't pick up a stale last_scan_log_xyz.txt (and that we have rights to the file) + if (File.Exists(this.dvdInfoPath)) + { + File.Delete(this.dvdInfoPath); + } + } + catch (Exception exc) + { + Debug.WriteLine(exc); + } + + if (!Directory.Exists(Path.GetDirectoryName(this.dvdInfoPath))) + { + Directory.CreateDirectory(Path.GetDirectoryName(this.dvdInfoPath)); + } + + // Create a new scan log. + this.scanLog = new StreamWriter(this.dvdInfoPath); + + // Create a new HandBrake Instance. + HandBrakeUtils.MessageLogged += this.HandBrakeInstanceMessageLogged; + HandBrakeUtils.ErrorLogged += this.HandBrakeInstanceErrorLogged; + this.instance = HandBrakeInstanceManager.GetScanInstance(configuraiton.Verbosity); + this.instance.ScanProgress += this.InstanceScanProgress; + this.instance.ScanCompleted += this.InstanceScanCompleted; + + // Start the scan on a back + this.ScanSource(sourcePath, title, configuraiton.PreviewScanCount, configuraiton); + } + + /// + /// Kill the scan + /// + public void Stop() + { + try + { + this.ServiceLogMessage("Stopping Scan."); + this.IsScanning = false; + this.instance.StopScan(); + + lock (LogLock) + { + if (this.scanLog != null) + { + this.scanLog.Close(); + this.scanLog.Dispose(); + this.scanLog = null; + } + } + } + catch (Exception) + { + // Do Nothing. + } + } + + /// + /// Get a Preview image for the current job and preview number. + /// + /// + /// The job. + /// + /// + /// The preview. + /// + /// + /// The configuraiton. + /// + /// + /// The . + /// + public BitmapImage GetPreview(EncodeTask job, int preview, HBConfiguration configuraiton) + { + if (this.instance == null) + { + return null; + } + + BitmapImage bitmapImage = null; + try + { + PreviewSettings settings = new PreviewSettings + { + Cropping = new Cropping(job.Cropping), + MaxWidth = job.MaxWidth ?? 0, + MaxHeight = job.MaxHeight ?? 0, + KeepDisplayAspect = job.KeepDisplayAspect, + TitleNumber = job.Title, + Anamorphic = job.Anamorphic, + Modulus = job.Modulus, + Width = job.Width ?? 0, + Height = job.Height ?? 0, + PixelAspectX = job.PixelAspectX, + PixelAspectY = job.PixelAspectY + }; + + bitmapImage = this.instance.GetPreview(settings, preview); + } + catch (AccessViolationException e) + { + Console.WriteLine(e); + } + + return bitmapImage; + } + + #endregion + + #region Private Methods + + /// + /// Start a scan for a given source path and title + /// + /// + /// Path to the source file + /// + /// + /// the title number to look at + /// + /// + /// The preview Count. + /// + /// + /// The configuraiton. + /// + private void ScanSource(object sourcePath, int title, int previewCount, HBConfiguration configuraiton) + { + try + { + this.logging.Clear(); + + string source = sourcePath.ToString().EndsWith("\\") ? string.Format("\"{0}\\\\\"", sourcePath.ToString().TrimEnd('\\')) + : "\"" + sourcePath + "\""; + this.currentSourceScanPath = source; + + this.IsScanning = true; + + TimeSpan minDuration = TimeSpan.FromSeconds(configuraiton.MinScanDuration); + + HandBrakeUtils.SetDvdNav(!configuraiton.IsDvdNavDisabled); + + this.ServiceLogMessage("Starting Scan ..."); + this.instance.StartScan(sourcePath.ToString(), previewCount, minDuration, title != 0 ? title : 0); + + if (this.ScanStarted != null) + this.ScanStarted(this, System.EventArgs.Empty); + } + catch (Exception exc) + { + this.ServiceLogMessage("Scan Failed ..." + Environment.NewLine + exc); + this.Stop(); + + if (this.ScanCompleted != null) + this.ScanCompleted(this, new ScanCompletedEventArgs(false, exc, "An Error has occured in ScanService.ScanSource()", null)); + } + } + + #endregion + + #region HandBrakeInstance Event Handlers + /// + /// Scan Completed Event Handler + /// + /// + /// The sender. + /// + /// + /// The EventArgs. + /// + private void InstanceScanCompleted(object sender, System.EventArgs e) + { + this.ServiceLogMessage("Scan Finished ..."); + + // Write the log file out before we start processing incase we crash. + try + { + if (this.scanLog != null) + { + this.scanLog.Flush(); + } + } + catch (Exception exc) + { + Debug.WriteLine(exc); + } + + HandBrakeUtils.MessageLogged -= this.HandBrakeInstanceMessageLogged; + HandBrakeUtils.ErrorLogged -= this.HandBrakeInstanceErrorLogged; + + // TODO -> Might be a better place to fix this. + string path = this.currentSourceScanPath; + if (this.currentSourceScanPath.Contains("\"")) + { + path = this.currentSourceScanPath.Trim('\"'); + } + + // Process into internal structures. + Source sourceData = null; + if (this.instance != null && this.instance.Titles != null) + { + sourceData = new Source { Titles = ConvertTitles(this.instance.Titles), ScanPath = path }; + } + + this.IsScanning = false; + + if (this.postScanOperation != null) + { + try + { + this.postScanOperation(true, sourceData); + } + catch (Exception exc) + { + Debug.WriteLine(exc); + } + + this.postScanOperation = null; // Reset + } + else + { + if (this.ScanCompleted != null) this.ScanCompleted(this, new ScanCompletedEventArgs(false, null, string.Empty, sourceData)); + } + } + + /// + /// Scan Progress Event Handler + /// + /// + /// The sender. + /// + /// + /// The EventArgs. + /// + private void InstanceScanProgress(object sender, ScanProgressEventArgs e) + { + if (this.ScanStatusChanged != null) + { + HandBrakeWPF.Services.Scan.EventArgs.ScanProgressEventArgs eventArgs = + new HandBrakeWPF.Services.Scan.EventArgs.ScanProgressEventArgs + { + CurrentTitle = e.CurrentTitle, + Titles = e.Titles, + Percentage = Math.Round((decimal)e.Progress * 100, 0) + }; + + this.ScanStatusChanged(this, eventArgs); + } + } + + /// + /// Log a message + /// + /// + /// The sender. + /// + /// + /// The MessageLoggedEventArgs. + /// + private void HandBrakeInstanceErrorLogged(object sender, MessageLoggedEventArgs e) + { + this.LogMessage(e.Message); + } + + /// + /// Log a message + /// + /// + /// The sender. + /// + /// + /// The MessageLoggedEventArgs. + /// + private void HandBrakeInstanceMessageLogged(object sender, MessageLoggedEventArgs e) + { + this.LogMessage(e.Message); + } + + /// + /// Convert Interop Title objects to App Services Title object + /// + /// + /// The titles. + /// + /// + /// The convert titles. + /// + internal static List ConvertTitles(JsonScanObject titles) + { + List<Title> titleList = new List<Title>(); + foreach (SourceTitle title in titles.TitleList) + { + Title converted = new Title + { + TitleNumber = title.Index, + Duration = new TimeSpan(0, title.Duration.Hours, title.Duration.Minutes, title.Duration.Seconds), + Resolution = new Size(title.Geometry.Width, title.Geometry.Height), + AngleCount = title.AngleCount, + ParVal = new Size(title.Geometry.PAR.Num, title.Geometry.PAR.Den), + AutoCropDimensions = new Cropping + { + Top = title.Crop[0], + Bottom = title.Crop[1], + Left = title.Crop[2], + Right = title.Crop[3] + }, + Fps = ((double)title.FrameRate.Num) / title.FrameRate.Den, + SourceName = title.Path, + MainTitle = titles.MainFeature == title.Index, + Playlist = title.Type == 1 ? string.Format(" {0:d5}.MPLS", title.Playlist).Trim() : null, + FramerateNumerator = title.FrameRate.Num, + FramerateDenominator = title.FrameRate.Den + }; + + int currentTrack = 1; + foreach (SourceChapter chapter in title.ChapterList) + { + string chapterName = !string.IsNullOrEmpty(chapter.Name) ? chapter.Name : string.Empty; + converted.Chapters.Add(new Chapter(currentTrack, chapterName, new TimeSpan(chapter.Duration.Hours, chapter.Duration.Minutes, chapter.Duration.Seconds))); + currentTrack++; + } + + int currentAudioTrack = 1; + foreach (SourceAudioTrack track in title.AudioList) + { + converted.AudioTracks.Add(new Audio(currentAudioTrack, track.Language, track.LanguageCode, track.Description, string.Empty, track.SampleRate, track.BitRate)); + currentAudioTrack++; + } + + int currentSubtitleTrack = 1; + foreach (SourceSubtitleTrack track in title.SubtitleList) + { + SubtitleType convertedType = new SubtitleType(); + + switch (track.Source) + { + case 0: + convertedType = SubtitleType.VobSub; + break; + case 4: + convertedType = SubtitleType.UTF8Sub; + break; + case 5: + convertedType = SubtitleType.TX3G; + break; + case 6: + convertedType = SubtitleType.SSA; + break; + case 1: + convertedType = SubtitleType.SRT; + break; + case 2: + convertedType = SubtitleType.CC; + break; + case 3: + convertedType = SubtitleType.CC; + break; + case 7: + convertedType = SubtitleType.PGS; + break; + } + + bool canBurn = HBFunctions.hb_subtitle_can_burn(track.Source) > 0; + bool canSetForcedOnly = HBFunctions.hb_subtitle_can_force(track.Source) > 0; + + converted.Subtitles.Add(new Subtitle(track.Source, currentSubtitleTrack, track.Language, track.LanguageCode, convertedType, canBurn, canSetForcedOnly)); + currentSubtitleTrack++; + } + + titleList.Add(converted); + } + + return titleList; + } + + /// <summary> + /// The log message. + /// </summary> + /// <param name="message"> + /// The message. + /// </param> + private void LogMessage(string message) + { + lock (LogLock) + { + if (this.scanLog != null) + { + this.scanLog.WriteLine(message); + } + + this.logging.AppendLine(message); + } + } + + /// <summary> + /// The service log message. + /// </summary> + /// <param name="message"> + /// The message. + /// </param> + protected void ServiceLogMessage(string message) + { + this.LogMessage(string.Format("# {0}", message)); + } + #endregion + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/Scan/Model/Audio.cs b/win/CS/HandBrakeWPF/Services/Scan/Model/Audio.cs new file mode 100644 index 000000000..1f0a2af98 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Scan/Model/Audio.cs @@ -0,0 +1,181 @@ +// -------------------------------------------------------------------------------------------------------------------- +// <copyright file="Audio.cs" company="HandBrake Project (http://handbrake.fr)"> +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// </copyright> +// <summary> +// An object represending an AudioTrack associated with a Title, in a DVD +// </summary> +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Scan.Model +{ + using System; + + /// <summary> + /// An object represending an AudioTrack associated with a Title, in a DVD + /// </summary> + [Serializable] + public class Audio + { + /// <summary> + /// Initializes a new instance of the <see cref="Audio"/> class. + /// </summary> + public Audio() + { + } + + /// <summary> + /// Initializes a new instance of the <see cref="Audio"/> class. + /// </summary> + /// <param name="trackNumber"> + /// The track number. + /// </param> + /// <param name="language"> + /// The language. + /// </param> + /// <param name="languageCode"> + /// The language code. + /// </param> + /// <param name="description"> + /// The description. + /// </param> + /// <param name="format"> + /// The format. + /// </param> + /// <param name="sampleRate"> + /// The sample rate. + /// </param> + /// <param name="bitrate"> + /// The bitrate. + /// </param> + public Audio(int trackNumber, string language, string languageCode, string description, string format, int sampleRate, int bitrate) + { + this.TrackNumber = trackNumber; + this.Language = language; + this.LanguageCode = languageCode; + this.Description = description; + this.Format = format; + this.SampleRate = sampleRate; + this.Bitrate = bitrate; + } + + /// <summary> + /// Gets or sets The track number of this Audio Track + /// </summary> + public int TrackNumber { get; set; } + + /// <summary> + /// Gets or sets The language (if detected) of this Audio Track + /// </summary> + public string Language { get; set; } + + /// <summary> + /// Gets or sets LanguageCode. + /// </summary> + public string LanguageCode { get; set; } + + /// <summary> + /// Gets or sets Description. + /// </summary> + public string Description { get; set; } + + /// <summary> + /// Gets or sets The primary format of this Audio Track + /// </summary> + public string Format { get; set; } + + /// <summary> + /// Gets or sets The frequency (in MHz) of this Audio Track + /// </summary> + public int SampleRate { get; set; } + + /// <summary> + /// Gets or sets The bitrate (in kbps) of this Audio Track + /// </summary> + public int Bitrate { get; set; } + + /// <summary> + /// Override of the ToString method to make this object easier to use in the UI + /// </summary> + /// <returns>A string formatted as: {track #} {language} ({format}) ({sub-format})</returns> + public override string ToString() + { + if (this.Description == "None Found") + { + return this.Description; + } + + return string.Format("{0} {1}", this.TrackNumber, this.Description); + } + + /// <summary> + /// The equals. + /// </summary> + /// <param name="other"> + /// The other. + /// </param> + /// <returns> + /// The System.Boolean. + /// </returns> + public bool Equals(Audio other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + return other.TrackNumber == this.TrackNumber && object.Equals(other.Language, this.Language) && object.Equals(other.LanguageCode, this.LanguageCode) && object.Equals(other.Format, this.Format); + } + + /// <summary> + /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>. + /// </summary> + /// <returns> + /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false. + /// </returns> + /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>. </param><filterpriority>2</filterpriority> + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != typeof(Audio)) + { + return false; + } + + return this.Equals((Audio)obj); + } + + /// <summary> + /// Serves as a hash function for a particular type. + /// </summary> + /// <returns> + /// A hash code for the current <see cref="T:System.Object"/>. + /// </returns> + /// <filterpriority>2</filterpriority> + public override int GetHashCode() + { + unchecked + { + int result = this.TrackNumber; + result = (result * 397) ^ (this.Language != null ? this.Language.GetHashCode() : 0); + result = (result * 397) ^ (this.LanguageCode != null ? this.LanguageCode.GetHashCode() : 0); + result = (result * 397) ^ (this.Format != null ? this.Format.GetHashCode() : 0); + return result; + } + } + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/Scan/Model/Chapter.cs b/win/CS/HandBrakeWPF/Services/Scan/Model/Chapter.cs new file mode 100644 index 000000000..bc817a29c --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Scan/Model/Chapter.cs @@ -0,0 +1,70 @@ +// -------------------------------------------------------------------------------------------------------------------- +// <copyright file="Chapter.cs" company="HandBrake Project (http://handbrake.fr)"> +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// </copyright> +// <summary> +// An object representing a Chapter aosciated with a Title, in a DVD +// </summary> +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Scan.Model +{ + using System; + using System.Globalization; + + /// <summary> + /// An object representing a Chapter aosciated with a Title, in a DVD + /// </summary> + public class Chapter + { + /// <summary> + /// Initializes a new instance of the <see cref="Chapter"/> class. + /// </summary> + public Chapter() + { + } + + /// <summary> + /// Initializes a new instance of the <see cref="Chapter"/> class. + /// </summary> + /// <param name="number"> + /// The number. + /// </param> + /// <param name="name"> + /// The name. + /// </param> + /// <param name="duration"> + /// The duration. + /// </param> + public Chapter(int number, string name, TimeSpan duration) + { + this.ChapterName = name; + this.ChapterNumber = number; + this.Duration = duration; + } + + /// <summary> + /// Gets or sets The number of this Chapter, in regards to it's parent Title + /// </summary> + public int ChapterNumber { get; set; } + + /// <summary> + /// Gets or sets ChapterName. + /// </summary> + public string ChapterName { get; set; } + + /// <summary> + /// Gets or sets The length in time this Chapter spans + /// </summary> + public TimeSpan Duration { get; set; } + + /// <summary> + /// Override of the ToString method to make this object easier to use in the UI + /// </summary> + /// <returns>A string formatted as: {chapter #}</returns> + public override string ToString() + { + return this.ChapterNumber.ToString(CultureInfo.InvariantCulture); + } + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/Scan/Model/Source.cs b/win/CS/HandBrakeWPF/Services/Scan/Model/Source.cs new file mode 100644 index 000000000..b8e3bcdaf --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Scan/Model/Source.cs @@ -0,0 +1,57 @@ +// -------------------------------------------------------------------------------------------------------------------- +// <copyright file="Source.cs" company="HandBrake Project (http://handbrake.fr)"> +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// </copyright> +// <summary> +// An object representing a scanned DVD +// </summary> +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Scan.Model +{ + using System.Collections.Generic; + using System.Runtime.Serialization; + using System.Xml.Serialization; + + /// <summary> + /// An object representing a scanned DVD + /// </summary> + [DataContract] + public class Source + { + /// <summary> + /// Initializes a new instance of the <see cref="Source"/> class. + /// Default constructor for this object + /// </summary> + public Source() + { + this.Titles = new List<Title>(); + } + + /// <summary> + /// Gets or sets ScanPath. + /// The Path used by the Scan Service. + /// </summary> + [DataMember] + public string ScanPath { get; set; } + + /// <summary> + /// Gets or sets Titles. A list of titles from the source + /// </summary> + [DataMember] + [XmlIgnore] + public List<Title> Titles { get; set; } + + /// <summary> + /// Copy this Source to another Source Model + /// </summary> + /// <param name="source"> + /// The source. + /// </param> + public void CopyTo(Source source) + { + source.Titles = this.Titles; + source.ScanPath = this.ScanPath; + } + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/Scan/Model/Subtitle.cs b/win/CS/HandBrakeWPF/Services/Scan/Model/Subtitle.cs new file mode 100644 index 000000000..920ef711e --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Scan/Model/Subtitle.cs @@ -0,0 +1,207 @@ +// -------------------------------------------------------------------------------------------------------------------- +// <copyright file="Subtitle.cs" company="HandBrake Project (http://handbrake.fr)"> +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// </copyright> +// <summary> +// An object that represents a subtitle associated with a Title, in a DVD +// </summary> +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Scan.Model +{ + using System; + using System.Xml.Serialization; + + using HandBrake.ApplicationServices.Utilities; + + using HandBrakeWPF.Services.Encode.Model.Models; + + /// <summary> + /// An object that represents a subtitle associated with a Title, in a DVD + /// </summary> + public class Subtitle + { + /// <summary> + /// Initializes a new instance of the <see cref="Subtitle"/> class. + /// </summary> + public Subtitle() + { + } + + /// <summary> + /// Initializes a new instance of the <see cref="Subtitle"/> class. + /// </summary> + /// <param name="sourceId"> + /// The source Id. + /// </param> + /// <param name="trackNumber"> + /// The track number. + /// </param> + /// <param name="language"> + /// The language. + /// </param> + /// <param name="languageCode"> + /// The language code. + /// </param> + /// <param name="subtitleType"> + /// The subtitle type. + /// </param> + /// <param name="canBurn"> + /// The can Burn. + /// </param> + /// <param name="canForce"> + /// The can Force. + /// </param> + public Subtitle(int sourceId, int trackNumber, string language, string languageCode, SubtitleType subtitleType, bool canBurn, bool canForce) + { + this.SourceId = sourceId; + this.TrackNumber = trackNumber; + this.Language = language; + this.LanguageCode = languageCode; + this.SubtitleType = subtitleType; + this.CanBurnIn = canBurn; + this.CanForce = canForce; + } + + /// <summary> + /// Gets or sets the source id. + /// </summary> + public int SourceId { get; set; } + + /// <summary> + /// Gets or sets the track number of this Subtitle + /// </summary> + public int TrackNumber { get; set; } + + /// <summary> + /// Gets or sets the The language (if detected) of this Subtitle + /// </summary> + public string Language { get; set; } + + /// <summary> + /// Gets or sets the Langauage Code + /// </summary> + public string LanguageCode { get; set; } + + /// <summary> + /// Gets the language code clean. + /// TODO Remove this after fixing language code. + /// </summary> + public string LanguageCodeClean + { + get + { + if (this.LanguageCode != null) + { + return this.LanguageCode.Replace("iso639-2: ", string.Empty).Trim(); + } + return string.Empty; + } + } + + /// <summary> + /// Gets a value indicating whether can burn in. + /// </summary> + [XmlIgnore] + public bool CanBurnIn { get; private set; } + + /// <summary> + /// Gets a value indicating whether can force. + /// </summary> + [XmlIgnore] + public bool CanForce { get; private set; } + + /// <summary> + /// Gets or sets the Subtitle Type + /// </summary> + public SubtitleType SubtitleType { get; set; } + + /// <summary> + /// Gets Subtitle Type + /// </summary> + public string TypeString + { + get + { + return EnumHelper<Enum>.GetDescription(this.SubtitleType); + } + } + + /// <summary> + /// Override of the ToString method to make this object easier to use in the UI + /// </summary> + /// <returns>A string formatted as: {track #} {language}</returns> + public override string ToString() + { + return this.SubtitleType == SubtitleType.ForeignAudioSearch ? "Foreign Audio Scan" : string.Format("{0} {1} ({2})", this.TrackNumber, this.Language, this.TypeString); + } + + /// <summary> + /// The equals. + /// </summary> + /// <param name="other"> + /// The other. + /// </param> + /// <returns> + /// The System.Boolean. + /// </returns> + public bool Equals(Subtitle other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + if (ReferenceEquals(this, other)) + { + return true; + } + return other.TrackNumber == this.TrackNumber && object.Equals(other.Language, this.Language) && object.Equals(other.LanguageCode, this.LanguageCode) && object.Equals(other.SubtitleType, this.SubtitleType); + } + + /// <summary> + /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>. + /// </summary> + /// <returns> + /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false. + /// </returns> + /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>. </param><filterpriority>2</filterpriority> + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != typeof(Subtitle)) + { + return false; + } + + return this.Equals((Subtitle)obj); + } + + /// <summary> + /// Serves as a hash function for a particular type. + /// </summary> + /// <returns> + /// A hash code for the current <see cref="T:System.Object"/>. + /// </returns> + /// <filterpriority>2</filterpriority> + public override int GetHashCode() + { + unchecked + { + int result = this.TrackNumber; + result = (result * 397) ^ (this.Language != null ? this.Language.GetHashCode() : 0); + result = (result * 397) ^ (this.LanguageCode != null ? this.LanguageCode.GetHashCode() : 0); + result = (result * 397) ^ this.SubtitleType.GetHashCode(); + return result; + } + } + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/Scan/Model/Title.cs b/win/CS/HandBrakeWPF/Services/Scan/Model/Title.cs new file mode 100644 index 000000000..32fddb36d --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Scan/Model/Title.cs @@ -0,0 +1,159 @@ +// -------------------------------------------------------------------------------------------------------------------- +// <copyright file="Title.cs" company="HandBrake Project (http://handbrake.fr)"> +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// </copyright> +// <summary> +// An object that represents a single Title of a DVD +// </summary> +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services.Scan.Model +{ + using System; + using System.Collections.Generic; + using System.Linq; + + using HandBrake.ApplicationServices.Interop.Model; + + /// <summary> + /// An object that represents a single Title of a DVD + /// </summary> + public class Title + { + /// <summary> + /// Initializes a new instance of the <see cref="Title"/> class. + /// </summary> + public Title() + { + this.AudioTracks = new List<Audio>(); + this.Chapters = new List<Chapter>(); + this.Subtitles = new List<Subtitle>(); + } + + #region Properties + + /// <summary> + /// Gets or sets a Collection of chapters in this Title + /// </summary> + public List<Chapter> Chapters { get; set; } + + /// <summary> + /// Gets or sets a Collection of audio tracks associated with this Title + /// </summary> + public List<Audio> AudioTracks { get; set; } + + /// <summary> + /// Gets or sets a Collection of subtitles associated with this Title + /// </summary> + public List<Subtitle> Subtitles { get; set; } + + /// <summary> + /// Gets or sets The track number of this Title + /// </summary> + public int TitleNumber { get; set; } + + /// <summary> + /// Gets or sets the type. + /// HB_DVD_TYPE, HB_BD_TYPE, HB_STREAM_TYPE, HB_FF_STREAM_TYPE + /// </summary> + public int Type { get; set; } + + /// <summary> + /// Gets or sets Playlist. + /// </summary> + public string Playlist { get; set; } + + /// <summary> + /// Gets or sets the length in time of this Title + /// </summary> + public TimeSpan Duration { get; set; } + + /// <summary> + /// Gets or sets the resolution (width/height) of this Title + /// </summary> + public Size Resolution { get; set; } + + /// <summary> + /// Gets or sets the aspect ratio of this Title + /// </summary> + public decimal AspectRatio { get; set; } + + /// <summary> + /// Gets or sets AngleCount. + /// </summary> + public int AngleCount { get; set; } + + /// <summary> + /// Gets or sets Par Value + /// </summary> + public Size ParVal { get; set; } + + /// <summary> + /// Gets or sets the automatically detected crop region for this Title. + /// This is an int array with 4 items in it as so: + /// 0: T + /// 1: B + /// 2: L + /// 3: R + /// </summary> + public Cropping AutoCropDimensions { get; set; } + + /// <summary> + /// Gets or sets the FPS of the source. + /// </summary> + public double Fps { get; set; } + + /// <summary> + /// Gets or sets the video frame rate numerator. + /// </summary> + public int FramerateNumerator { get; set; } + + /// <summary> + /// Gets or sets the video frame rate denominator. + /// </summary> + public int FramerateDenominator { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether this is a MainTitle. + /// </summary> + public bool MainTitle { get; set; } + + /// <summary> + /// Gets or sets the Source Name + /// </summary> + public string SourceName { get; set; } + + #endregion + + /// <summary> + /// Calcuate the Duration + /// </summary> + /// <param name="startPoint">The Start Point (Chapters)</param> + /// <param name="endPoint">The End Point (Chapters)</param> + /// <returns>A Timespan</returns> + public TimeSpan CalculateDuration(int startPoint, int endPoint) + { + IEnumerable<Chapter> chapers = + this.Chapters.Where(c => c.ChapterNumber >= startPoint && c.ChapterNumber <= endPoint); + + TimeSpan duration = TimeSpan.FromSeconds(0.0); + duration = chapers.Aggregate(duration, (current, chapter) => current + chapter.Duration); + + return duration; + } + + /// <summary> + /// Override of the ToString method to provide an easy way to use this object in the UI + /// </summary> + /// <returns>A string representing this track in the format: {title #} (00:00:00)</returns> + public override string ToString() + { + if (!string.IsNullOrEmpty(this.Playlist) && !this.Playlist.StartsWith(" ")) + { + this.Playlist = string.Format(" {0}", this.Playlist); + } + + return string.Format("{0}{1} ({2:00}:{3:00}:{4:00})", this.TitleNumber, this.Playlist, this.Duration.Hours, this.Duration.Minutes, this.Duration.Seconds); + } + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs b/win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs index c2ca7b3ad..43d8de44f 100644 --- a/win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs +++ b/win/CS/HandBrakeWPF/Startup/AppBootstrapper.cs @@ -11,15 +11,9 @@ namespace HandBrakeWPF.Startup { using System; using System.Collections.Generic; - using System.Reflection; using Caliburn.Micro; - using HandBrake.ApplicationServices.Services.Encode; - using HandBrake.ApplicationServices.Services.Encode.Interfaces; - using HandBrake.ApplicationServices.Services.Scan; - using HandBrake.ApplicationServices.Services.Scan.Interfaces; - using HandBrakeWPF.Commands; using HandBrakeWPF.Commands.Interfaces; using HandBrakeWPF.Services; @@ -28,9 +22,14 @@ namespace HandBrakeWPF.Startup using HandBrakeWPF.Services.Presets.Interfaces; using HandBrakeWPF.Services.Queue; using HandBrakeWPF.Services.Queue.Interfaces; + using HandBrakeWPF.Services.Scan; + using HandBrakeWPF.Services.Scan.Interfaces; using HandBrakeWPF.ViewModels; using HandBrakeWPF.ViewModels.Interfaces; + using IEncode = HandBrakeWPF.Services.Encode.Interfaces.IEncode; + using LibEncode = HandBrakeWPF.Services.Encode.LibEncode; + /// <summary> /// The Castle Bootstrapper /// </summary> diff --git a/win/CS/HandBrakeWPF/ViewModels/AddPresetViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/AddPresetViewModel.cs index 5246bd58f..6ef7f01f5 100644 --- a/win/CS/HandBrakeWPF/ViewModels/AddPresetViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/AddPresetViewModel.cs @@ -12,8 +12,6 @@ namespace HandBrakeWPF.ViewModels using System.Collections.Generic; using System.Windows; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Scan.Model; using HandBrake.ApplicationServices.Utilities; using HandBrake.ApplicationServices.Interop.Model.Encoding; @@ -24,8 +22,10 @@ namespace HandBrakeWPF.ViewModels using HandBrakeWPF.Services.Presets; using HandBrakeWPF.Services.Presets.Interfaces; using HandBrakeWPF.Services.Presets.Model; + using HandBrakeWPF.Services.Scan.Model; using HandBrakeWPF.ViewModels.Interfaces; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; using PresetPictureSettingsMode = HandBrakeWPF.Model.Picture.PresetPictureSettingsMode; /// <summary> diff --git a/win/CS/HandBrakeWPF/ViewModels/AdvancedViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/AdvancedViewModel.cs index c4fc78868..069f097e7 100644 --- a/win/CS/HandBrakeWPF/ViewModels/AdvancedViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/AdvancedViewModel.cs @@ -9,13 +9,14 @@ namespace HandBrakeWPF.ViewModels { - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Scan.Model; using HandBrake.ApplicationServices.Interop.Model.Encoding; using HandBrakeWPF.Services.Presets.Model; + using HandBrakeWPF.Services.Scan.Model; using HandBrakeWPF.ViewModels.Interfaces; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + /// <summary> /// The Advanced View Model /// </summary> diff --git a/win/CS/HandBrakeWPF/ViewModels/AudioViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/AudioViewModel.cs index be7c2bb0e..d732b0cd6 100644 --- a/win/CS/HandBrakeWPF/ViewModels/AudioViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/AudioViewModel.cs @@ -18,17 +18,21 @@ namespace HandBrakeWPF.ViewModels using HandBrake.ApplicationServices.Interop; using HandBrake.ApplicationServices.Interop.Model.Encoding; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; - using HandBrake.ApplicationServices.Services.Scan.Model; using HandBrake.ApplicationServices.Utilities; using HandBrakeWPF.Model.Audio; using HandBrakeWPF.Properties; using HandBrakeWPF.Services.Interfaces; using HandBrakeWPF.Services.Presets.Model; + using HandBrakeWPF.Services.Scan.Model; using HandBrakeWPF.ViewModels.Interfaces; + using AllowedPassthru = HandBrakeWPF.Services.Encode.Model.Models.AllowedPassthru; + using AudioEncoder = HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder; + using AudioTrack = HandBrakeWPF.Services.Encode.Model.Models.AudioTrack; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + using OutputFormat = HandBrakeWPF.Services.Encode.Model.Models.OutputFormat; + /// <summary> /// The Audio View Model /// </summary> diff --git a/win/CS/HandBrakeWPF/ViewModels/ChaptersViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/ChaptersViewModel.cs index d1353d029..7971357fd 100644 --- a/win/CS/HandBrakeWPF/ViewModels/ChaptersViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/ChaptersViewModel.cs @@ -17,19 +17,20 @@ namespace HandBrakeWPF.ViewModels using Caliburn.Micro; using HandBrake.ApplicationServices.Exceptions; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; - using HandBrake.ApplicationServices.Services.Scan.Model; using HandBrakeWPF.Properties; using HandBrakeWPF.Services.Interfaces; using HandBrakeWPF.Services.Presets.Model; + using HandBrakeWPF.Services.Scan.Model; using HandBrakeWPF.ViewModels.Interfaces; using LumenWorks.Framework.IO.Csv; using Microsoft.Win32; + using ChapterMarker = HandBrakeWPF.Services.Encode.Model.Models.ChapterMarker; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + /// <summary> /// The Chapters View Model /// </summary> diff --git a/win/CS/HandBrakeWPF/ViewModels/FiltersViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/FiltersViewModel.cs index d34c0f954..07906b204 100644 --- a/win/CS/HandBrakeWPF/ViewModels/FiltersViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/FiltersViewModel.cs @@ -14,16 +14,18 @@ namespace HandBrakeWPF.ViewModels using Caliburn.Micro; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; - using HandBrake.ApplicationServices.Services.Scan.Model; using HandBrake.ApplicationServices.Utilities; using HandBrake.ApplicationServices.Interop.Model.Encoding; using HandBrakeWPF.Services.Interfaces; using HandBrakeWPF.Services.Presets.Model; + using HandBrakeWPF.Services.Scan.Model; using HandBrakeWPF.ViewModels.Interfaces; + using DenoisePreset = HandBrakeWPF.Services.Encode.Model.Models.DenoisePreset; + using DenoiseTune = HandBrakeWPF.Services.Encode.Model.Models.DenoiseTune; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + /// <summary> /// The Filters View Model /// </summary> diff --git a/win/CS/HandBrakeWPF/ViewModels/Interfaces/IAddPresetViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IAddPresetViewModel.cs index beee9d226..4a5ad7b08 100644 --- a/win/CS/HandBrakeWPF/ViewModels/Interfaces/IAddPresetViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IAddPresetViewModel.cs @@ -9,12 +9,11 @@ namespace HandBrakeWPF.ViewModels.Interfaces { - using HandBrake.ApplicationServices.Model; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Scan.Model; - using HandBrakeWPF.Model.Audio; using HandBrakeWPF.Model.Subtitles; + using HandBrakeWPF.Services.Scan.Model; + + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; /// <summary> /// The Add Preset View Model diff --git a/win/CS/HandBrakeWPF/ViewModels/Interfaces/IMainViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IMainViewModel.cs index 38e0d5913..c886e70ba 100644 --- a/win/CS/HandBrakeWPF/ViewModels/Interfaces/IMainViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IMainViewModel.cs @@ -11,11 +11,10 @@ namespace HandBrakeWPF.ViewModels.Interfaces { using System.Windows; - using HandBrake.ApplicationServices.Model; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrakeWPF.Services.Presets.Model; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + /// <summary> /// The Main Window View Model /// </summary> diff --git a/win/CS/HandBrakeWPF/ViewModels/Interfaces/IQueueSelectionViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IQueueSelectionViewModel.cs index 67e8f14d0..1b5f3f0b6 100644 --- a/win/CS/HandBrakeWPF/ViewModels/Interfaces/IQueueSelectionViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IQueueSelectionViewModel.cs @@ -13,9 +13,8 @@ namespace HandBrakeWPF.ViewModels.Interfaces using System.Collections.Generic; using System.ComponentModel; - using HandBrake.ApplicationServices.Services.Scan.Model; - using HandBrakeWPF.Model; + using HandBrakeWPF.Services.Scan.Model; /// <summary> /// The Add Preset View Model diff --git a/win/CS/HandBrakeWPF/ViewModels/Interfaces/IStaticPreviewViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IStaticPreviewViewModel.cs index aa2ba9d1b..919a62170 100644 --- a/win/CS/HandBrakeWPF/ViewModels/Interfaces/IStaticPreviewViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/Interfaces/IStaticPreviewViewModel.cs @@ -9,8 +9,9 @@ namespace HandBrakeWPF.ViewModels.Interfaces { - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Scan.Model; + using HandBrakeWPF.Services.Scan.Model; + + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; /// <summary> /// The Static Preview View Model Interface diff --git a/win/CS/HandBrakeWPF/ViewModels/Interfaces/ITabInterface.cs b/win/CS/HandBrakeWPF/ViewModels/Interfaces/ITabInterface.cs index 43a536ab4..3e3ca0466 100644 --- a/win/CS/HandBrakeWPF/ViewModels/Interfaces/ITabInterface.cs +++ b/win/CS/HandBrakeWPF/ViewModels/Interfaces/ITabInterface.cs @@ -9,10 +9,10 @@ namespace HandBrakeWPF.ViewModels.Interfaces { - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Scan.Model; - using HandBrakeWPF.Services.Presets.Model; + using HandBrakeWPF.Services.Scan.Model; + + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; /// <summary> /// Common interface for all the main tab panels diff --git a/win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs index 99ab912a6..f9a26c1ed 100644 --- a/win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs @@ -13,13 +13,14 @@ namespace HandBrakeWPF.ViewModels using System.Diagnostics; using System.Windows; - using HandBrake.ApplicationServices.Services.Encode.EventArgs; - using HandBrake.ApplicationServices.Services.Encode.Interfaces; - using HandBrake.ApplicationServices.Services.Scan.EventArgs; - using HandBrake.ApplicationServices.Services.Scan.Interfaces; - + using HandBrakeWPF.Services.Scan.EventArgs; + using HandBrakeWPF.Services.Scan.Interfaces; using HandBrakeWPF.ViewModels.Interfaces; + using EncodeCompletedEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs; + using EncodeProgressEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeProgressEventArgs; + using IEncode = HandBrakeWPF.Services.Encode.Interfaces.IEncode; + /// <summary> /// The Log View Model /// </summary> diff --git a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs index 9e04cf396..23d23a498 100644 --- a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs @@ -21,16 +21,8 @@ namespace HandBrakeWPF.ViewModels using Caliburn.Micro; - using HandBrake.ApplicationServices.Services.Encode.EventArgs; - using HandBrake.ApplicationServices.Services.Encode.Interfaces; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; - using HandBrake.ApplicationServices.Services.Scan.EventArgs; - using HandBrake.ApplicationServices.Services.Scan.Interfaces; - using HandBrake.ApplicationServices.Services.Scan.Model; - using HandBrake.ApplicationServices.Utilities; using HandBrake.ApplicationServices.Interop; - using HandBrake.ApplicationServices.Interop.Json.Presets; + using HandBrake.ApplicationServices.Utilities; using HandBrakeWPF.Commands; using HandBrakeWPF.EventArgs; @@ -40,11 +32,18 @@ namespace HandBrakeWPF.ViewModels using HandBrakeWPF.Model.Audio; using HandBrakeWPF.Model.Subtitles; using HandBrakeWPF.Properties; + using HandBrakeWPF.Services.Encode.EventArgs; + using HandBrakeWPF.Services.Encode.Interfaces; + using HandBrakeWPF.Services.Encode.Model; + using HandBrakeWPF.Services.Encode.Model.Models; using HandBrakeWPF.Services.Interfaces; - using HandBrakeWPF.Services.Presets.Factories; using HandBrakeWPF.Services.Presets.Interfaces; using HandBrakeWPF.Services.Presets.Model; + using HandBrakeWPF.Services.Queue.Interfaces; using HandBrakeWPF.Services.Queue.Model; + using HandBrakeWPF.Services.Scan.EventArgs; + using HandBrakeWPF.Services.Scan.Interfaces; + using HandBrakeWPF.Services.Scan.Model; using HandBrakeWPF.Utilities; using HandBrakeWPF.ViewModels.Interfaces; using HandBrakeWPF.Views; @@ -55,7 +54,6 @@ namespace HandBrakeWPF.ViewModels using Action = System.Action; using Execute = Caliburn.Micro.Execute; - using IQueueProcessor = HandBrakeWPF.Services.Queue.Interfaces.IQueueProcessor; /// <summary> /// HandBrakes Main Window @@ -259,10 +257,10 @@ namespace HandBrakeWPF.ViewModels /// <param name="staticPreviewViewModel"> /// The static Preview View Model. /// </param> - public MainViewModel(IUserSettingService userSettingService, IScan scanService, IEncode encodeService, IPresetService presetService, - IErrorService errorService, IUpdateService updateService, - IPrePostActionService whenDoneService, IWindowManager windowManager, IPictureSettingsViewModel pictureSettingsViewModel, IVideoViewModel videoViewModel, - IFiltersViewModel filtersViewModel, IAudioViewModel audioViewModel, ISubtitlesViewModel subtitlesViewModel, + public MainViewModel(IUserSettingService userSettingService, IScan scanService, IEncode encodeService, IPresetService presetService, + IErrorService errorService, IUpdateService updateService, + IPrePostActionService whenDoneService, IWindowManager windowManager, IPictureSettingsViewModel pictureSettingsViewModel, IVideoViewModel videoViewModel, + IFiltersViewModel filtersViewModel, IAudioViewModel audioViewModel, ISubtitlesViewModel subtitlesViewModel, IAdvancedViewModel advancedViewModel, IChaptersViewModel chaptersViewModel, IStaticPreviewViewModel staticPreviewViewModel) { this.scanService = scanService; @@ -307,6 +305,7 @@ namespace HandBrakeWPF.ViewModels } #region View Model Properties + /// <summary> /// Gets or sets PictureSettingsViewModel. /// </summary> @@ -345,6 +344,7 @@ namespace HandBrakeWPF.ViewModels #endregion #region Properties + /// <summary> /// Gets or sets TestProperty. /// </summary> @@ -709,7 +709,7 @@ namespace HandBrakeWPF.ViewModels } set { - if (!object.Equals(this.CurrentTask.Destination, value)) + if (!Equals(this.CurrentTask.Destination, value)) { this.CurrentTask.Destination = value; this.NotifyOfPropertyChange(() => this.Destination); @@ -754,7 +754,7 @@ namespace HandBrakeWPF.ViewModels } set { - if (!object.Equals(this.selectedTitle, value)) + if (!Equals(this.selectedTitle, value)) { this.selectedTitle = value; @@ -957,7 +957,7 @@ namespace HandBrakeWPF.ViewModels set { - if (!object.Equals(this.selectedOutputFormat, value)) + if (!Equals(this.selectedOutputFormat, value)) { this.selectedOutputFormat = value; this.CurrentTask.OutputFormat = value; @@ -994,7 +994,7 @@ namespace HandBrakeWPF.ViewModels } set { - if (!object.Equals(this.isPresetPanelShowing, value)) + if (!Equals(this.isPresetPanelShowing, value)) { this.isPresetPanelShowing = value; this.NotifyOfPropertyChange(() => this.IsPresetPanelShowing); @@ -1039,9 +1039,9 @@ namespace HandBrakeWPF.ViewModels let driveInformation = item select new SourceMenuItem { - Text = string.Format("{0} ({1})", item.RootDirectory, item.VolumeLabel), - Command = new SourceMenuCommand(() => this.ProcessDrive(driveInformation)), - Tag = item, + Text = string.Format("{0} ({1})", item.RootDirectory, item.VolumeLabel), + Command = new SourceMenuCommand(() => this.ProcessDrive(driveInformation)), + Tag = item, IsDrive = true }) { @@ -1207,6 +1207,7 @@ namespace HandBrakeWPF.ViewModels #endregion #region Load and Shutdown Handling + /// <summary> /// Initialise this view model. /// </summary> @@ -1682,11 +1683,11 @@ namespace HandBrakeWPF.ViewModels { SaveFileDialog saveFileDialog = new SaveFileDialog { - Filter = "mp4|*.mp4;*.m4v|mkv|*.mkv", - CheckPathExists = true, - AddExtension = true, - DefaultExt = ".mp4", - OverwritePrompt = true, + Filter = "mp4|*.mp4;*.m4v|mkv|*.mkv", + CheckPathExists = true, + AddExtension = true, + DefaultExt = ".mp4", + OverwritePrompt = true, }; string extension = Path.GetExtension(this.CurrentTask.Destination); @@ -1806,9 +1807,9 @@ namespace HandBrakeWPF.ViewModels if (this.selectedPreset.IsDefault) { this.errorService.ShowMessageBox( - Resources.MainViewModel_CanNotDeleteDefaultPreset, - Resources.Warning, - MessageBoxButton.OK, + Resources.MainViewModel_CanNotDeleteDefaultPreset, + Resources.Warning, + MessageBoxButton.OK, MessageBoxImage.Information); return; @@ -1816,9 +1817,9 @@ namespace HandBrakeWPF.ViewModels MessageBoxResult result = this.errorService.ShowMessageBox( - Resources.MainViewModel_PresetRemove_AreYouSure + this.selectedPreset.Name + " ?", - Resources.Question, - MessageBoxButton.YesNo, + Resources.MainViewModel_PresetRemove_AreYouSure + this.selectedPreset.Name + " ?", + Resources.Question, + MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.No) @@ -1871,11 +1872,11 @@ namespace HandBrakeWPF.ViewModels { SaveFileDialog savefiledialog = new SaveFileDialog { - Filter = "json|*.json", - CheckPathExists = true, - AddExtension = true, - DefaultExt = ".json", - OverwritePrompt = true, + Filter = "json|*.json", + CheckPathExists = true, + AddExtension = true, + DefaultExt = ".json", + OverwritePrompt = true, FilterIndex = 0 }; if (this.selectedPreset != null) @@ -2120,6 +2121,7 @@ namespace HandBrakeWPF.ViewModels #endregion #region Event Handlers + /// <summary> /// Handle the Scan Status Changed Event. /// </summary> @@ -2220,7 +2222,7 @@ namespace HandBrakeWPF.ViewModels { int percent; int.TryParse( - Math.Round(e.PercentComplete).ToString(CultureInfo.InvariantCulture), + Math.Round(e.PercentComplete).ToString(CultureInfo.InvariantCulture), out percent); Execute.OnUIThread( @@ -2229,12 +2231,12 @@ namespace HandBrakeWPF.ViewModels if (this.queueProcessor.EncodeService.IsEncoding) { this.ProgramStatusLabel = - string.Format(Resources.MainViewModel_EncodeStatusChanged_StatusLabel + Resources.Main_JobsPending_addon, - e.PercentComplete, - e.CurrentFrameRate, - e.AverageFrameRate, - e.EstimatedTimeLeft, - e.ElapsedTime, + string.Format(Resources.MainViewModel_EncodeStatusChanged_StatusLabel + Resources.Main_JobsPending_addon, + e.PercentComplete, + e.CurrentFrameRate, + e.AverageFrameRate, + e.EstimatedTimeLeft, + e.ElapsedTime, this.queueProcessor.Count); if (lastEncodePercentage != percent && this.windowsSeven.IsWindowsSeven) @@ -2378,7 +2380,7 @@ namespace HandBrakeWPF.ViewModels /// <param name="e"> /// The e. /// </param> - private void CurrentTask_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + private void CurrentTask_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == UserSettingConstants.ShowAdvancedTab) { diff --git a/win/CS/HandBrakeWPF/ViewModels/MiniViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/MiniViewModel.cs index a532a990a..64809bbf4 100644 --- a/win/CS/HandBrakeWPF/ViewModels/MiniViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/MiniViewModel.cs @@ -11,14 +11,14 @@ namespace HandBrakeWPF.ViewModels { using System; - using HandBrake.ApplicationServices.Services.Encode.EventArgs; - using HandBrake.ApplicationServices.Services.Encode.Interfaces; - using HandBrakeWPF.EventArgs; using HandBrakeWPF.Properties; using HandBrakeWPF.Services.Queue.Interfaces; using HandBrakeWPF.ViewModels.Interfaces; + using EncodeProgressEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeProgressEventArgs; + using IEncode = HandBrakeWPF.Services.Encode.Interfaces.IEncode; + /// <summary> /// The mini view model. /// </summary> diff --git a/win/CS/HandBrakeWPF/ViewModels/PictureSettingsViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/PictureSettingsViewModel.cs index 90fd2b3ff..2d7267756 100644 --- a/win/CS/HandBrakeWPF/ViewModels/PictureSettingsViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/PictureSettingsViewModel.cs @@ -13,17 +13,17 @@ namespace HandBrakeWPF.ViewModels using System.Collections.Generic; using System.Globalization; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Scan.Model; using HandBrake.ApplicationServices.Interop.Model; using HandBrake.ApplicationServices.Interop.Model.Encoding; using HandBrakeWPF.Helpers; using HandBrakeWPF.Properties; using HandBrakeWPF.Services.Presets.Model; + using HandBrakeWPF.Services.Scan.Model; using HandBrakeWPF.Utilities; using HandBrakeWPF.ViewModels.Interfaces; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; using PresetPictureSettingsMode = HandBrakeWPF.Model.Picture.PresetPictureSettingsMode; /// <summary> diff --git a/win/CS/HandBrakeWPF/ViewModels/QueueSelectionViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/QueueSelectionViewModel.cs index a36f29e1b..ab790c234 100644 --- a/win/CS/HandBrakeWPF/ViewModels/QueueSelectionViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/QueueSelectionViewModel.cs @@ -14,11 +14,10 @@ namespace HandBrakeWPF.ViewModels using System.ComponentModel; using System.Linq; - using HandBrake.ApplicationServices.Services.Scan.Model; - using HandBrakeWPF.Model; using HandBrakeWPF.Properties; using HandBrakeWPF.Services.Interfaces; + using HandBrakeWPF.Services.Scan.Model; using HandBrakeWPF.ViewModels.Interfaces; /// <summary> diff --git a/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs index a8dde9dc2..324d9efe2 100644 --- a/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/QueueViewModel.cs @@ -18,8 +18,6 @@ namespace HandBrakeWPF.ViewModels using Caliburn.Micro; using HandBrake.ApplicationServices.Model; - using HandBrake.ApplicationServices.Services.Encode.EventArgs; - using HandBrake.ApplicationServices.Services.Encode.Model; using HandBrakeWPF.EventArgs; using HandBrakeWPF.Properties; @@ -30,6 +28,10 @@ namespace HandBrakeWPF.ViewModels using Microsoft.Win32; + using EncodeCompletedEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs; + using EncodeProgressEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeProgressEventArgs; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + /// <summary> /// The Preview View Model /// </summary> diff --git a/win/CS/HandBrakeWPF/ViewModels/StaticPreviewViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/StaticPreviewViewModel.cs index 48436cf86..09d27d029 100644 --- a/win/CS/HandBrakeWPF/ViewModels/StaticPreviewViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/StaticPreviewViewModel.cs @@ -20,20 +20,23 @@ namespace HandBrakeWPF.ViewModels using System.Windows.Media.Imaging; using HandBrake.ApplicationServices.Interop.Model.Encoding; - using HandBrake.ApplicationServices.Services.Encode; - using HandBrake.ApplicationServices.Services.Encode.EventArgs; - using HandBrake.ApplicationServices.Services.Encode.Interfaces; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; - using HandBrake.ApplicationServices.Services.Scan.Interfaces; - using HandBrake.ApplicationServices.Services.Scan.Model; using HandBrakeWPF.Factories; using HandBrakeWPF.Properties; using HandBrakeWPF.Services.Interfaces; using HandBrakeWPF.Services.Queue.Model; + using HandBrakeWPF.Services.Scan.Interfaces; + using HandBrakeWPF.Services.Scan.Model; using HandBrakeWPF.ViewModels.Interfaces; + using EncodeCompletedEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs; + using EncodeProgressEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeProgressEventArgs; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + using IEncode = HandBrakeWPF.Services.Encode.Interfaces.IEncode; + using LibEncode = HandBrakeWPF.Services.Encode.LibEncode; + using OutputFormat = HandBrakeWPF.Services.Encode.Model.Models.OutputFormat; + using PointToPointMode = HandBrakeWPF.Services.Encode.Model.Models.PointToPointMode; + /// <summary> /// The Static Preview View Model /// </summary> diff --git a/win/CS/HandBrakeWPF/ViewModels/SubtitlesViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/SubtitlesViewModel.cs index 751619c97..c2fefd4f6 100644 --- a/win/CS/HandBrakeWPF/ViewModels/SubtitlesViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/SubtitlesViewModel.cs @@ -14,18 +14,21 @@ namespace HandBrakeWPF.ViewModels using System.IO; using System.Linq; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; - using HandBrake.ApplicationServices.Services.Scan.Model; using HandBrake.ApplicationServices.Utilities; using HandBrakeWPF.Model.Subtitles; using HandBrakeWPF.Properties; using HandBrakeWPF.Services.Presets.Model; + using HandBrakeWPF.Services.Scan.Model; using HandBrakeWPF.ViewModels.Interfaces; using Microsoft.Win32; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + using OutputFormat = HandBrakeWPF.Services.Encode.Model.Models.OutputFormat; + using SubtitleTrack = HandBrakeWPF.Services.Encode.Model.Models.SubtitleTrack; + using SubtitleType = HandBrakeWPF.Services.Encode.Model.Models.SubtitleType; + /// <summary> /// The Subtitles View Model /// </summary> diff --git a/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs index 45b718bd8..0b263e3fa 100644 --- a/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs @@ -17,10 +17,6 @@ namespace HandBrakeWPF.ViewModels using Caliburn.Micro; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Encode.Model.Models; - using HandBrake.ApplicationServices.Services.Encode.Model.Models.Video; - using HandBrake.ApplicationServices.Services.Scan.Model; using HandBrake.ApplicationServices.Utilities; using HandBrake.ApplicationServices.Interop; using HandBrake.ApplicationServices.Interop.Model.Encoding; @@ -29,10 +25,18 @@ namespace HandBrakeWPF.ViewModels using HandBrakeWPF.Properties; using HandBrakeWPF.Services.Interfaces; using HandBrakeWPF.Services.Presets.Model; + using HandBrakeWPF.Services.Scan.Model; using HandBrakeWPF.ViewModels.Interfaces; using Clipboard = System.Windows.Clipboard; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + using FramerateMode = HandBrakeWPF.Services.Encode.Model.Models.FramerateMode; + using OutputFormat = HandBrakeWPF.Services.Encode.Model.Models.OutputFormat; using SettingChangedEventArgs = HandBrakeWPF.EventArgs.SettingChangedEventArgs; + using VideoLevel = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoLevel; + using VideoPreset = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoPreset; + using VideoProfile = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoProfile; + using VideoTune = HandBrakeWPF.Services.Encode.Model.Models.Video.VideoTune; /// <summary> /// The Video View Model diff --git a/win/CS/HandBrakeWPF/ViewModels/X264ViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/X264ViewModel.cs index b82e64c4e..2789dcc19 100644 --- a/win/CS/HandBrakeWPF/ViewModels/X264ViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/X264ViewModel.cs @@ -14,17 +14,17 @@ namespace HandBrakeWPF.ViewModels using System.Globalization; using System.Linq; - using HandBrake.ApplicationServices.Model; - using HandBrake.ApplicationServices.Services.Encode.Model; - using HandBrake.ApplicationServices.Services.Scan.Model; using HandBrake.ApplicationServices.Interop.Model.Encoding; using HandBrakeWPF.Commands.Interfaces; using HandBrakeWPF.Helpers; using HandBrakeWPF.Model; using HandBrakeWPF.Services.Presets.Model; + using HandBrakeWPF.Services.Scan.Model; using HandBrakeWPF.ViewModels.Interfaces; + using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask; + /// <summary> /// The Advanced View Model /// </summary> -- cgit v1.2.3