summaryrefslogtreecommitdiffstats
path: root/win/CS/HandBrakeWPF/Services/Encode
diff options
context:
space:
mode:
Diffstat (limited to 'win/CS/HandBrakeWPF/Services/Encode')
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/EncodeBase.cs380
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/EventArgs/EncodeCompletedEventArgs.cs68
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/EventArgs/EncodeProgressEventArgs.cs63
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Factories/EncodeFactory.cs542
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Factories/VideoLevelFactory.cs38
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Factories/VideoPresetFactory.cs63
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Factories/VideoProfileFactory.cs48
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Factories/VideoTuneFactory.cs54
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Interfaces/IEncode.cs119
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs262
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/EncodeTask.cs557
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/AllowedPassthru.cs172
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioEncoder.cs89
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioEncoderRateType.cs31
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/AudioTrack.cs636
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/ChapterMarker.cs92
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/DenoisePreset.cs45
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/DenoiseTune.cs41
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/FramerateMode.cs28
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/OutputFormat.cs32
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/PointToPointMode.cs31
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleTrack.cs275
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/SubtitleType.cs38
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoLevel.cs118
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoPreset.cs121
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoProfile.cs121
-rw-r--r--win/CS/HandBrakeWPF/Services/Encode/Model/Models/Video/VideoTune.cs137
27 files changed, 4201 insertions, 0 deletions
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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="EncodeBase.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>
+// A Base Class for the Encode Services.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+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;
+
+ /// <summary>
+ /// A Base Class for the Encode Services.
+ /// </summary>
+ public class EncodeBase
+ {
+ #region Private Variables
+
+ /// <summary>
+ /// A Lock for the filewriter
+ /// </summary>
+ private static readonly object FileWriterLock = new object();
+
+ /// <summary>
+ /// The Log File Header
+ /// </summary>
+ private readonly StringBuilder header;
+
+ /// <summary>
+ /// The Log Buffer
+ /// </summary>
+ private StringBuilder logBuffer;
+
+ /// <summary>
+ /// The Log file writer
+ /// </summary>
+ private StreamWriter fileWriter;
+
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="EncodeBase"/> class.
+ /// </summary>
+ public EncodeBase()
+ {
+ this.logBuffer = new StringBuilder();
+ this.header = GeneralUtilities.CreateLogHeader();
+ this.LogIndex = 0;
+ }
+
+ #region Events
+
+ /// <summary>
+ /// Fires when a new QueueTask starts
+ /// </summary>
+ public event EventHandler EncodeStarted;
+
+ /// <summary>
+ /// Fires when a QueueTask finishes.
+ /// </summary>
+ public event EncodeCompletedStatus EncodeCompleted;
+
+ /// <summary>
+ /// Encode process has progressed
+ /// </summary>
+ public event EncodeProgessStatus EncodeStatusChanged;
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets or sets a value indicating whether IsEncoding.
+ /// </summary>
+ public bool IsEncoding { get; protected set; }
+
+ /// <summary>
+ /// Gets ActivityLog.
+ /// </summary>
+ 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();
+ }
+ }
+
+ /// <summary>
+ /// Gets the log index.
+ /// </summary>
+ public int LogIndex { get; private set; }
+
+ /// <summary>
+ /// Gets LogBuffer.
+ /// </summary>
+ public StringBuilder LogBuffer
+ {
+ get
+ {
+ return this.logBuffer;
+ }
+ }
+
+ #endregion
+
+ #region Invoke Events
+
+ /// <summary>
+ /// Invoke the Encode Status Changed Event.
+ /// </summary>
+ /// <param name="e">
+ /// The EncodeProgressEventArgs.
+ /// </param>
+ public void InvokeEncodeStatusChanged(EncodeProgressEventArgs e)
+ {
+ EncodeProgessStatus handler = this.EncodeStatusChanged;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+ /// <summary>
+ /// Invoke the Encode Completed Event
+ /// </summary>
+ /// <param name="e">
+ /// The EncodeCompletedEventArgs.
+ /// </param>
+ public void InvokeEncodeCompleted(EncodeCompletedEventArgs e)
+ {
+ EncodeCompletedStatus handler = this.EncodeCompleted;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+
+ this.LogIndex = 0; // Reset
+ }
+
+ /// <summary>
+ /// Invoke the Encode Started Event
+ /// </summary>
+ /// <param name="e">
+ /// The EventArgs.
+ /// </param>
+ public void InvokeEncodeStarted(System.EventArgs e)
+ {
+ EventHandler handler = this.EncodeStarted;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+ #endregion
+
+ #region Methods
+
+ /// <summary>
+ /// Save a copy of the log to the users desired location or a default location
+ /// if this feature is enabled in options.
+ /// </summary>
+ /// <param name="destination">
+ /// The Destination File Path
+ /// </param>
+ /// <param name="configuration">
+ /// The configuration.
+ /// </param>
+ 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
+ }
+ }
+
+ /// <summary>
+ /// Setup the logging.
+ /// </summary>
+ 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;
+ }
+ }
+
+ /// <summary>
+ /// The service log message.
+ /// </summary>
+ /// <param name="message">
+ /// The message.
+ /// </param>
+ protected void ServiceLogMessage(string message)
+ {
+ this.ProcessLogMessage(string.Format("# {0}", message));
+ }
+
+ /// <summary>
+ /// Process an Incomming Log Message.
+ /// </summary>
+ /// <param name="message">
+ /// The message.
+ /// </param>
+ 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
+ }
+ }
+ }
+
+ /// <summary>
+ /// Shutdown and Dispose of the File Writer.
+ /// </summary>
+ 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
+ }
+ }
+
+ /// <summary>
+ /// Verify the Encode Destination path exists and if not, create it.
+ /// </summary>
+ /// <param name="task">
+ /// The task.
+ /// </param>
+ /// <exception cref="Exception">
+ /// If the creation fails, an exception is thrown.
+ /// </exception>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="EncodeCompletedEventArgs.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>
+// Encode Progress Event Args
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.EventArgs
+{
+ using System;
+ using System.Runtime.Serialization;
+
+ /// <summary>
+ /// Encode Progress Event Args
+ /// </summary>
+ [DataContract]
+ public class EncodeCompletedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="EncodeCompletedEventArgs"/> class.
+ /// </summary>
+ /// <param name="sucessful">
+ /// The sucessful.
+ /// </param>
+ /// <param name="exception">
+ /// The exception.
+ /// </param>
+ /// <param name="errorInformation">
+ /// The error information.
+ /// </param>
+ /// <param name="filename">
+ /// The filename.
+ /// </param>
+ public EncodeCompletedEventArgs(bool sucessful, Exception exception, string errorInformation, string filename)
+ {
+ this.Successful = sucessful;
+ this.Exception = exception;
+ this.ErrorInformation = errorInformation;
+ this.FileName = filename;
+ }
+
+ /// <summary>
+ /// Gets or sets the file name.
+ /// </summary>
+ [DataMember]
+ public string FileName { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether Successful.
+ /// </summary>
+ [DataMember]
+ public bool Successful { get; set; }
+
+ /// <summary>
+ /// Gets or sets Exception.
+ /// </summary>
+ [DataMember]
+ public Exception Exception { get; set; }
+
+ /// <summary>
+ /// Gets or sets ErrorInformation.
+ /// </summary>
+ [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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="EncodeProgressEventArgs.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>
+// Encode Progress Event Args
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.EventArgs
+{
+ using System;
+ using System.Runtime.Serialization;
+
+ /// <summary>
+ /// Encode Progress Event Args
+ /// </summary>
+ [DataContract]
+ public class EncodeProgressEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets or sets PercentComplete.
+ /// </summary>
+ [DataMember]
+ public double PercentComplete { get; set; }
+
+ /// <summary>
+ /// Gets or sets CurrentFrameRate.
+ /// </summary>
+ [DataMember]
+ public double CurrentFrameRate { get; set; }
+
+ /// <summary>
+ /// Gets or sets AverageFrameRate.
+ /// </summary>
+ [DataMember]
+ public double AverageFrameRate { get; set; }
+
+ /// <summary>
+ /// Gets or sets EstimatedTimeLeft.
+ /// </summary>
+ [DataMember]
+ public TimeSpan EstimatedTimeLeft { get; set; }
+
+ /// <summary>
+ /// Gets or sets Task.
+ /// </summary>
+ [DataMember]
+ public int Task { get; set; }
+
+ /// <summary>
+ /// Gets or sets TaskCount.
+ /// </summary>
+ [DataMember]
+ public int TaskCount { get; set; }
+
+ /// <summary>
+ /// Gets or sets ElapsedTime.
+ /// </summary>
+ [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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="EncodeFactory.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>
+// The encode factory.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+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;
+
+ /// <summary>
+ /// This factory takes the internal EncodeJob object and turns it into a set of JSON models
+ /// that can be deserialized by libhb.
+ /// </summary>
+ internal class EncodeFactory
+ {
+ /*
+ * TODO:
+ * 1. OpenCL and HWD Support
+ * 2. Rotate Support
+ */
+
+ /// <summary>
+ /// The create.
+ /// </summary>
+ /// <param name="job">
+ /// The encode job.
+ /// </param>
+ /// <param name="configuration">
+ /// The configuration.
+ /// </param>
+ /// <returns>
+ /// The <see cref="JsonEncodeObject"/>.
+ /// </returns>
+ 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;
+ }
+
+ /// <summary>
+ /// The create source.
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ /// <param name="configuration">
+ /// The configuration.
+ /// </param>
+ /// <returns>
+ /// The <see cref="Source"/>.
+ /// </returns>
+ 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;
+ }
+
+ /// <summary>
+ /// The create destination.
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ /// <returns>
+ /// The <see cref="Destination"/>.
+ /// </returns>
+ 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<Chapter>()
+ };
+
+ if (job.IncludeChapterMarkers)
+ {
+ foreach (ChapterMarker item in job.ChapterNames)
+ {
+ Chapter chapter = new Chapter { Name = item.ChapterName };
+ destination.ChapterList.Add(chapter);
+ }
+ }
+
+ return destination;
+ }
+
+ /// <summary>
+ /// Create the PAR object
+ /// </summary>
+ /// <param name="job">
+ /// The Job
+ /// </param>
+ /// <returns>
+ /// The produced PAR object.
+ /// </returns>
+ private static PAR CreatePAR(EncodeTask job)
+ {
+ return new PAR { Num = job.PixelAspectX, Den = job.PixelAspectY };
+ }
+
+ /// <summary>
+ /// The create subtitle.
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ /// <returns>
+ /// The <see cref="HandBrake.ApplicationServices.Interop.Json.Encode.Subtitles"/>.
+ /// </returns>
+ private static Subtitle CreateSubtitle(EncodeTask job)
+ {
+ Subtitles subtitle = new Subtitles
+ {
+ Search =
+ new SubtitleSearch
+ {
+ Enable = false,
+ Default = false,
+ Burn = false,
+ Forced = false
+ },
+ SubtitleList = new List<HandBrake.ApplicationServices.Interop.Json.Encode.SubtitleTrack>()
+ };
+
+ 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;
+ }
+
+ /// <summary>
+ /// The create video.
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ /// <param name="configuration">
+ /// The configuration.
+ /// </param>
+ /// <returns>
+ /// The <see cref="Video"/>.
+ /// </returns>
+ private static Video CreateVideo(EncodeTask job, HBConfiguration configuration)
+ {
+ Video video = new Video();
+
+ HBVideoEncoder videoEncoder = HandBrakeEncoderHelpers.VideoEncoders.FirstOrDefault(e => e.ShortName == EnumHelper<VideoEncoder>.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;
+ }
+
+ /// <summary>
+ /// The create audio.
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ /// <returns>
+ /// The <see cref="Audio"/>.
+ /// </returns>
+ private static Audio CreateAudio(EncodeTask job)
+ {
+ Audio audio = new Audio();
+
+ List<uint> copyMaskList = new List<uint>();
+ 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<AudioEncoder>.GetShortName(job.AllowedPassthruOptions.AudioEncoderFallback));
+ audio.FallbackEncoder = audioEncoder.Id;
+
+ audio.AudioList = new List<HandBrake.ApplicationServices.Interop.Json.Encode.AudioTrack>();
+ foreach (AudioTrack item in job.AudioTracks)
+ {
+ HBAudioEncoder encoder = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper<AudioEncoder>.GetShortName(item.Encoder));
+ Validate.NotNull(encoder, "Unrecognized audio encoder:" + item.Encoder);
+
+ HBMixdown mixdown = HandBrakeEncoderHelpers.GetMixdown(EnumHelper<Mixdown>.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;
+ }
+
+ /// <summary>
+ /// The create filter.
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ /// <returns>
+ /// The <see cref="Filters"/>.
+ /// </returns>
+ private static Filters CreateFilters(EncodeTask job)
+ {
+ Filters filter = new Filters
+ {
+ FilterList = new List<Filter>(),
+ 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;
+ }
+
+ /// <summary>
+ /// The create meta data.
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ /// <returns>
+ /// The <see cref="Metadata"/>.
+ /// </returns>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="VideoLevelFactory.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>
+// The video level factory.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Factories
+{
+ /// <summary>
+ /// The video tune factory.
+ /// </summary>
+ public class VideoLevelFactory
+ {
+ /// <summary>
+ /// The get display name for a given short name.
+ /// LibHB doesn't currently support this.
+ /// </summary>
+ /// <param name="shortName">
+ /// The short name.
+ /// </param>
+ /// <returns>
+ /// The <see cref="string"/>.
+ /// </returns>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="VideoPresetFactory.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>
+// The video preset factory.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Factories
+{
+ /// <summary>
+ /// The video tune factory.
+ /// </summary>
+ public class VideoPresetFactory
+ {
+ /// <summary>
+ /// The get display name for a given short name.
+ /// LibHB doesn't currently support this.
+ /// </summary>
+ /// <param name="shortName">
+ /// The short name.
+ /// </param>
+ /// <returns>
+ /// The <see cref="string"/>.
+ /// </returns>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="VideoProfileFactory.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>
+// The video profile factory.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Factories
+{
+ /// <summary>
+ /// The video profile factory.
+ /// </summary>
+ public class VideoProfileFactory
+ {
+ /// <summary>
+ /// The get display name for a given short name.
+ /// LibHB doesn't currently support this.
+ /// </summary>
+ /// <param name="shortName">
+ /// The short name.
+ /// </param>
+ /// <returns>
+ /// The <see cref="string"/>.
+ /// </returns>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="VideoTuneFactory.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>
+// The video tune factory.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Factories
+{
+ /// <summary>
+ /// The video tune factory.
+ /// </summary>
+ public class VideoTuneFactory
+ {
+ /// <summary>
+ /// The get display name for a given short name.
+ /// LibHB doesn't currently support this.
+ /// </summary>
+ /// <param name="shortName">
+ /// The short name.
+ /// </param>
+ /// <returns>
+ /// The <see cref="string"/>.
+ /// </returns>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="IEncode.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>
+// Encode Progess Status
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+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;
+
+ /// <summary>
+ /// Encode Progess Status
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The EncodeProgressEventArgs.
+ /// </param>
+ public delegate void EncodeProgessStatus(object sender, EncodeProgressEventArgs e);
+
+ /// <summary>
+ /// Encode Progess Status
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The EncodeProgressEventArgs.
+ /// </param>
+ public delegate void EncodeCompletedStatus(object sender, EncodeCompletedEventArgs e);
+
+ /// <summary>
+ /// The IEncode Interface
+ /// </summary>
+ public interface IEncode
+ {
+ /// <summary>
+ /// Fires when a new Job starts
+ /// </summary>
+ event EventHandler EncodeStarted;
+
+ /// <summary>
+ /// Fires when a job finishes.
+ /// </summary>
+ event EncodeCompletedStatus EncodeCompleted;
+
+ /// <summary>
+ /// Encode process has progressed
+ /// </summary>
+ event EncodeProgessStatus EncodeStatusChanged;
+
+ /// <summary>
+ /// Gets a value indicating whether IsEncoding.
+ /// </summary>
+ bool IsEncoding { get; }
+
+ /// <summary>
+ /// Gets ActivityLog.
+ /// </summary>
+ string ActivityLog { get; }
+
+ /// <summary>
+ /// Gets the log index. The current log row counter.
+ /// </summary>
+ int LogIndex { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether is pasued.
+ /// </summary>
+ bool IsPasued { get; }
+
+ /// <summary>
+ /// Start with a LibHb EncodeJob Object
+ /// </summary>
+ /// <param name="job">
+ /// The job.
+ /// </param>
+ /// <param name="configuration">
+ /// The configuration.
+ /// </param>
+ void Start(EncodeTask job, HBConfiguration configuration);
+
+ /// <summary>
+ /// The pause.
+ /// </summary>
+ void Pause();
+
+ /// <summary>
+ /// The resume.
+ /// </summary>
+ void Resume();
+
+ /// <summary>
+ /// Kill the process
+ /// </summary>
+ void Stop();
+
+ /// <summary>
+ /// Copy the log file to the desired destinations
+ /// </summary>
+ /// <param name="destination">
+ /// The destination.
+ /// </param>
+ /// <param name="configuration">
+ /// The configuration.
+ /// </param>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="LibEncode.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>
+// LibHB Implementation of IEncode
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+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;
+
+ /// <summary>
+ /// LibHB Implementation of IEncode
+ /// </summary>
+ 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
+
+ /// <summary>
+ /// Gets a value indicating whether is pasued.
+ /// </summary>
+ public bool IsPasued { get; private set; }
+
+ /// <summary>
+ /// Start with a LibHb EncodeJob Object
+ /// </summary>
+ /// <param name="task">
+ /// The task.
+ /// </param>
+ /// <param name="configuration">
+ /// The configuration.
+ /// </param>
+ 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));
+ }
+ }
+
+ /// <summary>
+ /// Pause the currently running encode.
+ /// </summary>
+ public void Pause()
+ {
+ if (this.instance != null)
+ {
+ this.instance.PauseEncode();
+ this.ServiceLogMessage("Encode Paused");
+ this.IsPasued = true;
+ }
+ }
+
+ /// <summary>
+ /// Resume the currently running encode.
+ /// </summary>
+ public void Resume()
+ {
+ if (this.instance != null)
+ {
+ this.instance.ResumeEncode();
+ this.ServiceLogMessage("Encode Resumed");
+ this.IsPasued = false;
+ }
+ }
+
+ /// <summary>
+ /// Kill the process
+ /// </summary>
+ 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.
+
+ /// <summary>
+ /// Log a message
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The MessageLoggedEventArgs.
+ /// </param>
+ private void HandBrakeInstanceErrorLogged(object sender, MessageLoggedEventArgs e)
+ {
+ lock (LogLock)
+ {
+ this.ProcessLogMessage(e.Message);
+ }
+ }
+
+ /// <summary>
+ /// Log a message
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The MessageLoggedEventArgs.
+ /// </param>
+ private void HandBrakeInstanceMessageLogged(object sender, MessageLoggedEventArgs e)
+ {
+ lock (LogLock)
+ {
+ this.ProcessLogMessage(e.Message);
+ }
+ }
+
+ /// <summary>
+ /// Encode Progress Event Handler
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The Interop.EncodeProgressEventArgs.
+ /// </param>
+ 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);
+ }
+
+ /// <summary>
+ /// Encode Completed Event Handler
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="EncodeTask.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 Encode Task
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+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;
+
+ /// <summary>
+ /// An Encode Task
+ /// </summary>
+ public class EncodeTask : PropertyChangedBase
+ {
+ #region Private Fields
+
+ /// <summary>
+ /// The advanced panel enabled.
+ /// </summary>
+ private bool showAdvancedTab;
+
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="EncodeTask"/> class.
+ /// </summary>
+ public EncodeTask()
+ {
+ this.Cropping = new Cropping();
+ this.AudioTracks = new ObservableCollection<AudioTrack>();
+ this.SubtitleTracks = new ObservableCollection<SubtitleTrack>();
+ this.ChapterNames = new ObservableCollection<ChapterMarker>();
+ this.AllowedPassthruOptions = new AllowedPassthru();
+ this.Modulus = 16;
+
+ this.VideoTunes = new List<VideoTune>();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="EncodeTask"/> class.
+ /// Copy Constructor
+ /// </summary>
+ /// <param name="task">
+ /// The task.
+ /// </param>
+ 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<AudioTrack>();
+ foreach (AudioTrack track in task.AudioTracks)
+ {
+ this.AudioTracks.Add(new AudioTrack(track, true));
+ }
+
+ this.ChapterNames = new ObservableCollection<ChapterMarker>();
+ 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<SubtitleTrack>();
+ 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
+
+ /// <summary>
+ /// Gets or sets Source.
+ /// </summary>
+ public string Source { get; set; }
+
+ /// <summary>
+ /// Gets or sets Title.
+ /// </summary>
+ public int Title { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Angle
+ /// </summary>
+ public int Angle { get; set; }
+
+ /// <summary>
+ /// Gets or sets PointToPointMode.
+ /// </summary>
+ public PointToPointMode PointToPointMode { get; set; }
+
+ /// <summary>
+ /// Gets or sets StartPoint.
+ /// </summary>
+ public int StartPoint { get; set; }
+
+ /// <summary>
+ /// Gets or sets EndPoint.
+ /// </summary>
+ public int EndPoint { get; set; }
+
+ #endregion
+
+ #region Destination
+
+ /// <summary>
+ /// Gets or sets Destination.
+ /// </summary>
+ public string Destination { get; set; }
+
+ #endregion
+
+ #region Output Settings
+
+ /// <summary>
+ /// Gets or sets OutputFormat.
+ /// </summary>
+ public OutputFormat OutputFormat { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether Optimize.
+ /// </summary>
+ public bool OptimizeMP4 { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether IPod5GSupport.
+ /// </summary>
+ public bool IPod5GSupport { get; set; }
+
+ #endregion
+
+ #region Picture
+
+ /// <summary>
+ /// Gets or sets Width.
+ /// </summary>
+ public int? Width { get; set; }
+
+ /// <summary>
+ /// Gets or sets Height.
+ /// </summary>
+ public int? Height { get; set; }
+
+ /// <summary>
+ /// Gets or sets MaxWidth.
+ /// </summary>
+ public int? MaxWidth { get; set; }
+
+ /// <summary>
+ /// Gets or sets MaxHeight.
+ /// </summary>
+ public int? MaxHeight { get; set; }
+
+ /// <summary>
+ /// Gets or sets Cropping.
+ /// </summary>
+ public Cropping Cropping { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether HasCropping.
+ /// </summary>
+ public bool HasCropping { get; set; }
+
+ /// <summary>
+ /// Gets or sets Anamorphic.
+ /// </summary>
+ public Anamorphic Anamorphic { get; set; }
+
+ /// <summary>
+ /// Gets or sets DisplayWidth.
+ /// </summary>
+ public double? DisplayWidth { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether KeepDisplayAspect.
+ /// </summary>
+ public bool KeepDisplayAspect { get; set; }
+
+ /// <summary>
+ /// Gets or sets PixelAspectX.
+ /// </summary>
+ public int PixelAspectX { get; set; }
+
+ /// <summary>
+ /// Gets or sets PixelAspectY.
+ /// </summary>
+ public int PixelAspectY { get; set; }
+
+ /// <summary>
+ /// Gets or sets Modulus.
+ /// </summary>
+ public int? Modulus { get; set; }
+
+ #endregion
+
+ #region Filters
+
+ /// <summary>
+ /// Gets or sets Deinterlace.
+ /// </summary>
+ public Deinterlace Deinterlace { get; set; }
+
+ /// <summary>
+ /// Gets or sets CustomDeinterlace.
+ /// </summary>
+ public string CustomDeinterlace { get; set; }
+
+ /// <summary>
+ /// Gets or sets Decomb.
+ /// </summary>
+ public Decomb Decomb { get; set; }
+
+ /// <summary>
+ /// Gets or sets CustomDecomb.
+ /// </summary>
+ public string CustomDecomb { get; set; }
+
+ /// <summary>
+ /// Gets or sets Detelecine.
+ /// </summary>
+ public Detelecine Detelecine { get; set; }
+
+ /// <summary>
+ /// Gets or sets CustomDetelecine.
+ /// </summary>
+ public string CustomDetelecine { get; set; }
+
+ /// <summary>
+ /// Gets or sets Denoise.
+ /// </summary>
+ public Denoise Denoise { get; set; }
+
+ /// <summary>
+ /// Gets or sets the denoise preset.
+ /// </summary>
+ public DenoisePreset DenoisePreset { get; set; }
+
+ /// <summary>
+ /// Gets or sets the denoise tune.
+ /// </summary>
+ public DenoiseTune DenoiseTune { get; set; }
+
+ /// <summary>
+ /// Gets or sets CustomDenoise.
+ /// </summary>
+ public string CustomDenoise { get; set; }
+
+ /// <summary>
+ /// Gets or sets Deblock.
+ /// </summary>
+ public int Deblock { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether Grayscale.
+ /// </summary>
+ public bool Grayscale { get; set; }
+
+ #endregion
+
+ #region Video
+
+ /// <summary>
+ /// Gets or sets VideoEncodeRateType.
+ /// </summary>
+ public VideoEncodeRateType VideoEncodeRateType { get; set; }
+
+ /// <summary>
+ /// Gets or sets the VideoEncoder
+ /// </summary>
+ public VideoEncoder VideoEncoder { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Video Encode Mode
+ /// </summary>
+ public FramerateMode FramerateMode { get; set; }
+
+ /// <summary>
+ /// Gets or sets Quality.
+ /// </summary>
+ public double? Quality { get; set; }
+
+ /// <summary>
+ /// Gets or sets VideoBitrate.
+ /// </summary>
+ public int? VideoBitrate { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether TwoPass.
+ /// </summary>
+ public bool TwoPass { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether TurboFirstPass.
+ /// </summary>
+ public bool TurboFirstPass { get; set; }
+
+ /// <summary>
+ /// Gets or sets Framerate.
+ /// Null = Same as Source
+ /// </summary>
+ public double? Framerate { get; set; }
+
+ #endregion
+
+ #region Audio
+
+ /// <summary>
+ /// Gets or sets AudioEncodings.
+ /// </summary>
+ public ObservableCollection<AudioTrack> AudioTracks { get; set; }
+
+ /// <summary>
+ /// Gets or sets AllowedPassthruOptions.
+ /// </summary>
+ public AllowedPassthru AllowedPassthruOptions { get; set; }
+
+ #endregion
+
+ #region Subtitles
+
+ /// <summary>
+ /// Gets or sets SubtitleTracks.
+ /// </summary>
+ public ObservableCollection<SubtitleTrack> SubtitleTracks { get; set; }
+
+ #endregion
+
+ #region Chapters
+
+ /// <summary>
+ /// Gets or sets a value indicating whether IncludeChapterMarkers.
+ /// </summary>
+ public bool IncludeChapterMarkers { get; set; }
+
+ /// <summary>
+ /// Gets or sets ChapterMarkersFilePath.
+ /// </summary>
+ public string ChapterMarkersFilePath { get; set; }
+
+ /// <summary>
+ /// Gets or sets ChapterNames.
+ /// </summary>
+ public ObservableCollection<ChapterMarker> ChapterNames { get; set; }
+
+ #endregion
+
+ #region Advanced
+
+ /// <summary>
+ /// Gets or sets AdvancedEncoderOptions.
+ /// </summary>
+ public string AdvancedEncoderOptions { get; set; }
+
+ /// <summary>
+ /// Gets or sets the video profile.
+ /// </summary>
+ public VideoProfile VideoProfile { get; set; }
+
+ /// <summary>
+ /// Gets or sets the video level.
+ /// </summary>
+ public VideoLevel VideoLevel { get; set; }
+
+ /// <summary>
+ /// Gets or sets the video preset.
+ /// </summary>
+ public VideoPreset VideoPreset { get; set; }
+
+ /// <summary>
+ /// Gets or sets the video tunes.
+ /// </summary>
+ public List<VideoTune> VideoTunes { get; set; }
+
+ /// <summary>
+ /// Gets or sets Extra Advanced Arguments for the Video Tab.
+ /// </summary>
+ public string ExtraAdvancedArguments { get; set; }
+
+ #endregion
+
+ #region Preview
+
+ /// <summary>
+ /// Gets or sets a value indicating whether IsPreviewEncode.
+ /// </summary>
+ public bool IsPreviewEncode { get; set; }
+
+ /// <summary>
+ /// Gets or sets PreviewEncodeDuration.
+ /// </summary>
+ public int? PreviewEncodeDuration { get; set; }
+
+ /// <summary>
+ /// Gets or sets PreviewEncodeStartAt.
+ /// </summary>
+ public int? PreviewEncodeStartAt { get; set; }
+
+ #endregion
+
+ #region Helpers
+
+ /// <summary>
+ /// Gets a value indicating whether M4v extension is required.
+ /// </summary>
+ 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;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether advanced panel enabled.
+ /// </summary>
+ public bool ShowAdvancedTab
+ {
+ get
+ {
+ return this.showAdvancedTab;
+ }
+ set
+ {
+ if (!Equals(value, this.showAdvancedTab))
+ {
+ this.showAdvancedTab = value;
+ this.NotifyOfPropertyChange(() => this.ShowAdvancedTab);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the picture settings desc.
+ /// </summary>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="AllowedPassthru.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>
+// Allowed Passthru Options
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models
+{
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Allowed Passthru Options
+ /// </summary>
+ public class AllowedPassthru
+ {
+ #region Constructors and Destructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AllowedPassthru"/> class.
+ /// </summary>
+ 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;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AllowedPassthru"/> class.
+ /// </summary>
+ /// <param name="initialValue">
+ /// The initial Value.
+ /// </param>
+ 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;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AllowedPassthru"/> class.
+ /// Copy Constructor
+ /// </summary>
+ /// <param name="initialValue">
+ /// The initial value.
+ /// </param>
+ 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
+
+ /// <summary>
+ /// Gets or sets a value indicating whether AudioAllowAACPass.
+ /// </summary>
+ public bool AudioAllowAACPass { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether AudioAllowAC3Pass.
+ /// </summary>
+ public bool AudioAllowAC3Pass { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether AudioAllowDTSHDPass.
+ /// </summary>
+ public bool AudioAllowDTSHDPass { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether AudioAllowDTSPass.
+ /// </summary>
+ public bool AudioAllowDTSPass { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether AudioAllowMP3Pass.
+ /// </summary>
+ public bool AudioAllowMP3Pass { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether audio allow true hd pass.
+ /// </summary>
+ public bool AudioAllowTrueHDPass { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether audio allow flac pass.
+ /// </summary>
+ public bool AudioAllowFlacPass { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether audio allow ea c 3 pass.
+ /// </summary>
+ public bool AudioAllowEAC3Pass { get; set; }
+
+ /// <summary>
+ /// Gets or sets AudioEncoderFallback.
+ /// </summary>
+ public AudioEncoder AudioEncoderFallback { get; set; }
+
+ /// <summary>
+ /// Gets the allowed passthru options.
+ /// </summary>
+ public IEnumerable<AudioEncoder> AllowedPassthruOptions
+ {
+ get
+ {
+ List<AudioEncoder> audioEncoders = new List<AudioEncoder>();
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="AudioEncoder.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>
+// The audio encoder enumeration
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models
+{
+ using System.ComponentModel.DataAnnotations;
+
+ using HandBrake.ApplicationServices.Attributes;
+
+ /// <summary>
+ /// The audio encoder.
+ /// </summary>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="AudioEncoderRateType.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>
+// The audio encoder rate type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models
+{
+ using System.ComponentModel.DataAnnotations;
+
+ /// <summary>
+ /// The audio encoder rate type.
+ /// </summary>
+ public enum AudioEncoderRateType
+ {
+ /// <summary>
+ /// The bitrate.
+ /// </summary>
+ [Display(Name = "Bitrate: ")]
+ Bitrate,
+
+ /// <summary>
+ /// The quality.
+ /// </summary>
+ [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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="AudioTrack.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>
+// Model of a HandBrake Audio Track and it's associated behaviours.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+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;
+
+ /// <summary>
+ /// Model of a HandBrake Audio Track and it's associated behaviours.
+ /// </summary>
+ 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<int> bitrates;
+ private IEnumerable<double> encoderQualityValues;
+ private HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType encoderRateType;
+ private double? quality;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref = "AudioTrack" /> class.
+ /// </summary>
+ 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();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="AudioTrack"/> class.
+ /// Copy Constructor
+ /// </summary>
+ /// <param name="track">
+ /// The track.
+ /// </param>
+ /// <param name="setScannedTrack">
+ /// The set Scanned Track.
+ /// </param>
+ 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
+
+ /// <summary>
+ /// Gets or sets Dynamic Range Compression
+ /// </summary>
+ public double DRC
+ {
+ get
+ {
+ return this.drc;
+ }
+
+ set
+ {
+ if (!Equals(value, this.drc))
+ {
+ this.drc = value;
+ this.NotifyOfPropertyChange(() => this.DRC);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the Gain for the audio track
+ /// </summary>
+ public int Gain
+ {
+ get
+ {
+ return this.gain;
+ }
+
+ set
+ {
+ if (!Equals(value, this.gain))
+ {
+ this.gain = value;
+ this.NotifyOfPropertyChange(() => this.Gain);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets Audio Mixdown
+ /// </summary>
+ public Mixdown MixDown
+ {
+ get
+ {
+ return this.mixDown;
+ }
+
+ set
+ {
+ this.mixDown = value;
+ this.NotifyOfPropertyChange(() => this.MixDown);
+ this.SetupLimits();
+ this.NotifyOfPropertyChange(() => this.TrackReference);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets Audio Encoder
+ /// </summary>
+ 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.
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets Audio SampleRate
+ /// </summary>
+ public double SampleRate
+ {
+ get
+ {
+ return this.sampleRate;
+ }
+
+ set
+ {
+ this.sampleRate = value;
+ this.NotifyOfPropertyChange(() => this.SampleRate);
+ this.SetupLimits();
+ this.NotifyOfPropertyChange(() => this.TrackReference);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the encoder rate type.
+ /// </summary>
+ 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<HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder>.GetShortName(this.Encoder));
+ this.Quality = HandBrakeEncoderHelpers.GetDefaultQuality(hbAudioEncoder);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets Audio Bitrate
+ /// </summary>
+ public int Bitrate
+ {
+ get
+ {
+ return this.bitrate;
+ }
+
+ set
+ {
+ this.bitrate = value;
+ this.NotifyOfPropertyChange(() => this.Bitrate);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets Audio quality
+ /// </summary>
+ public double? Quality
+ {
+ get
+ {
+ return this.quality;
+ }
+
+ set
+ {
+ this.quality = value;
+ this.NotifyOfPropertyChange(() => this.quality);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the track name.
+ /// </summary>
+ public string TrackName { get; set; }
+ #endregion
+
+ /// <summary>
+ /// Gets AudioEncoderDisplayValue.
+ /// </summary>
+ [JsonIgnore]
+ public string AudioEncoderDisplayValue
+ {
+ get
+ {
+ return EnumHelper<HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder>.GetDisplay(this.Encoder);
+ }
+ }
+
+ /// <summary>
+ /// Gets AudioMixdownDisplayValue.
+ /// </summary>
+ [JsonIgnore]
+ public string AudioMixdownDisplayValue
+ {
+ get
+ {
+ return EnumHelper<Mixdown>.GetDisplay(this.MixDown);
+ }
+ }
+
+ /// <summary>
+ /// Gets the The UI display value for bit rate
+ /// </summary>
+ [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();
+ }
+ }
+
+ /// <summary>
+ /// 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.
+ /// </summary>
+ [JsonIgnore]
+ public bool IsDefault
+ {
+ get
+ {
+ return this.isDefault;
+ }
+ set
+ {
+ this.isDefault = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the The UI display value for sample rate
+ /// </summary>
+ [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;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the Scanned Audio Tracks
+ /// </summary>
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public Audio ScannedTrack
+ {
+ get
+ {
+ return this.scannedTrack;
+ }
+
+ set
+ {
+ this.scannedTrack = value;
+ this.NotifyOfPropertyChange(() => this.ScannedTrack);
+ }
+ }
+
+ /// <summary>
+ /// Gets the Audio Track Name
+ /// </summary>
+ [JsonIgnore]
+ public int? Track
+ {
+ get
+ {
+ if (this.ScannedTrack != null)
+ {
+ return this.ScannedTrack.TrackNumber;
+ }
+
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether IsPassthru.
+ /// </summary>
+ [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;
+ }
+ }
+
+ /// <summary>
+ /// Gets the bitrates.
+ /// </summary>
+ [JsonIgnore]
+ public IEnumerable<int> Bitrates
+ {
+ get
+ {
+ return this.bitrates;
+ }
+ }
+
+ /// <summary>
+ /// Gets the quality compression values.
+ /// </summary>
+ [JsonIgnore]
+ public IEnumerable<double> EncoderQualityValues
+ {
+ get
+ {
+ return this.encoderQualityValues;
+ }
+ }
+
+ /// <summary>
+ /// Gets the audio encoder rate types.
+ /// </summary>
+ [JsonIgnore]
+ public IEnumerable<HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType> AudioEncoderRateTypes
+ {
+ get
+ {
+ IList<HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType> types = EnumHelper<HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType>.GetEnumList().ToList();
+ HBAudioEncoder hbaenc = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper<HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder>.GetShortName(this.Encoder));
+ if (hbaenc == null || !hbaenc.SupportsQuality)
+ {
+ types.Remove(HandBrakeWPF.Services.Encode.Model.Models.AudioEncoderRateType.Quality);
+ }
+
+ return types;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether can set bitrate.
+ /// </summary>
+ [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);
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether is quality visible.
+ /// </summary>
+ [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);
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether is rate type visible.
+ /// </summary>
+ [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;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether IsLossless.
+ /// </summary>
+ [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;
+ }
+ }
+
+ /// <summary>
+ /// Gets TrackReference.
+ /// </summary>
+ [JsonIgnore]
+ public AudioTrack TrackReference
+ {
+ get { return this; }
+ }
+
+ #region Handler Methods
+
+ /// <summary>
+ /// The setup limits.
+ /// </summary>
+ private void SetupLimits()
+ {
+ this.SetupBitrateLimits();
+ this.SetupQualityCompressionLimits();
+ }
+
+ /// <summary>
+ /// The calculate bitrate limits.
+ /// </summary>
+ private void SetupBitrateLimits()
+ {
+ // Base set of bitrates available.
+ List<int> 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<HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder>.GetShortName(this.Encoder));
+ HBRate rate = HandBrakeEncoderHelpers.AudioSampleRates.FirstOrDefault(t => t.Name == this.SampleRate.ToString(CultureInfo.InvariantCulture));
+ HBMixdown mixdown = HandBrakeEncoderHelpers.GetMixdown(EnumHelper<Mixdown>.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<int> 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);
+ }
+ }
+
+ /// <summary>
+ /// The setup quality compression limits.
+ /// </summary>
+ private void SetupQualityCompressionLimits()
+ {
+ HBAudioEncoder hbAudioEncoder = HandBrakeEncoderHelpers.GetAudioEncoder(EnumHelper<HandBrakeWPF.Services.Encode.Model.Models.AudioEncoder>.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<double> values = new List<double> { 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<double>();
+ }
+ }
+ else
+ {
+ this.encoderQualityValues = new List<double>();
+ }
+
+ // 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="ChapterMarker.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>
+// A Movie Chapter
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models
+{
+ using System;
+
+ using HandBrake.ApplicationServices.Utilities;
+
+ /// <summary>
+ /// A Movie Chapter
+ /// </summary>
+ public class ChapterMarker : PropertyChangedBase
+ {
+ /// <summary>
+ /// Backing field for chapter name
+ /// </summary>
+ private string chapterName;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ChapterMarker"/> class.
+ /// </summary>
+ public ChapterMarker()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ChapterMarker"/> class.
+ /// </summary>
+ /// <param name="number">
+ /// The number.
+ /// </param>
+ /// <param name="name">
+ /// The name.
+ /// </param>
+ /// <param name="duration">
+ /// The duration.
+ /// </param>
+ public ChapterMarker(int number, string name, TimeSpan duration)
+ {
+ this.ChapterName = name;
+ this.ChapterNumber = number;
+ this.Duration = duration;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ChapterMarker"/> class.
+ /// Copy Constructor
+ /// </summary>
+ /// <param name="chapter">
+ /// The chapter.
+ /// </param>
+ public ChapterMarker(ChapterMarker chapter)
+ {
+ this.ChapterName = chapter.ChapterName;
+ this.ChapterNumber = chapter.ChapterNumber;
+ this.Duration = chapter.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 the duration.
+ /// </summary>
+ public TimeSpan Duration { get; set; }
+
+ /// <summary>
+ /// Gets or sets ChapterName.
+ /// </summary>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="DenoisePreset.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>
+// Defines the DenoisePreset type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models
+{
+ using System.ComponentModel.DataAnnotations;
+
+ using HandBrake.ApplicationServices.Attributes;
+
+ /// <summary>
+ /// The denoise preset.
+ /// </summary>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="DenoiseTune.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>
+// Defines the DenoiseTune type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models
+{
+ using System.ComponentModel.DataAnnotations;
+
+ using HandBrake.ApplicationServices.Attributes;
+
+ /// <summary>
+ /// The denoise tune.
+ /// </summary>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="FramerateMode.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>
+// The Mode of Video Encoding. CFR, VFR, PFR
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models
+{
+ using HandBrake.ApplicationServices.Attributes;
+
+ /// <summary>
+ /// The Mode of Video Encoding. CFR, VFR, PFR
+ /// </summary>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="OutputFormat.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>
+// The Output format.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models
+{
+ using System.ComponentModel;
+ using System.ComponentModel.DataAnnotations;
+
+ using HandBrake.ApplicationServices.Attributes;
+
+ /// <summary>
+ /// The Output format.
+ /// </summary>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="PointToPointMode.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>
+// Point to Point Mode
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models
+{
+ using System.ComponentModel.DataAnnotations;
+
+ /// <summary>
+ /// Point to Point Mode
+ /// </summary>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="SubtitleTrack.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>
+// Subtitle Information
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models
+{
+ using System;
+
+ using HandBrake.ApplicationServices.Utilities;
+
+ using HandBrakeWPF.Services.Scan.Model;
+
+ /// <summary>
+ /// Subtitle Information
+ /// </summary>
+ public class SubtitleTrack : PropertyChangedBase
+ {
+ #region Constants and Fields
+
+ /// <summary>
+ /// The burned in backing field.
+ /// </summary>
+ private bool burned;
+
+ /// <summary>
+ /// The is default backing field.
+ /// </summary>
+ private bool isDefault;
+
+ /// <summary>
+ /// The source track.
+ /// </summary>
+ private Subtitle sourceTrack;
+
+ /// <summary>
+ /// Backing field for the srt file name.
+ /// </summary>
+ private string srtFileName;
+
+ /// <summary>
+ /// Backing field for Forced Subs
+ /// </summary>
+ private bool forced;
+
+ #endregion
+
+ #region Constructors and Destructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SubtitleTrack"/> class.
+ /// </summary>
+ public SubtitleTrack()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SubtitleTrack"/> class.
+ /// Copy Constructor
+ /// </summary>
+ /// <param name="subtitle">
+ /// The subtitle.
+ /// </param>
+ 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
+
+ /// <summary>
+ /// Gets or sets a value indicating whether Burned.
+ /// </summary>
+ 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;
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether Default.
+ /// </summary>
+ 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;
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether Forced.
+ /// </summary>
+ public bool Forced
+ {
+ get
+ {
+ return this.forced;
+ }
+ set
+ {
+ this.forced = value;
+ this.NotifyOfPropertyChange(() => this.Forced);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets SourceTrack.
+ /// </summary>
+ 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);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the SRT Character Code
+ /// </summary>
+ public string SrtCharCode { get; set; }
+
+ /// <summary>
+ /// Gets or sets the SRT Filename
+ /// </summary>
+ public string SrtFileName
+ {
+ get
+ {
+ return this.srtFileName;
+ }
+
+ set
+ {
+ this.srtFileName = value;
+ this.NotifyOfPropertyChange(() => this.IsSrtSubtitle);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the SRT Language
+ /// </summary>
+ public string SrtLang { get; set; }
+
+ /// <summary>
+ /// Gets or sets the SRT Offset
+ /// </summary>
+ public int SrtOffset { get; set; }
+
+ /// <summary>
+ /// Gets or sets the Path to the SRT file
+ /// </summary>
+ public string SrtPath { get; set; }
+
+ /// <summary>
+ /// Gets or sets the type of the subtitle
+ /// </summary>
+ public SubtitleType SubtitleType { get; set; }
+
+ /// <summary>
+ /// Gets or sets Track.
+ /// </summary>
+ [Obsolete("Use SourceTrack Instead")]
+ public string Track { get; set; }
+
+ #endregion
+
+ /// <summary>
+ /// Gets a value indicating whether CanForced.
+ /// </summary>
+ public bool CanBeForced
+ {
+ get
+ {
+ if (this.SourceTrack != null)
+ {
+ return this.SourceTrack.CanForce || this.SourceTrack.SubtitleType == SubtitleType.ForeignAudioSearch;
+ }
+
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether CanBeBurned.
+ /// </summary>
+ 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;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether this is an SRT subtitle.
+ /// </summary>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="SubtitleType.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>
+// Subtitle Type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models
+{
+ using System.ComponentModel;
+
+ /// <summary>
+ /// Subtitle Type.
+ /// </summary>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="VideoLevel.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>
+// The video level.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models.Video
+{
+ using VideoLevelFactory = HandBrakeWPF.Services.Encode.Factories.VideoLevelFactory;
+
+ /// <summary>
+ /// The video level.
+ /// </summary>
+ public class VideoLevel
+ {
+ /// <summary>
+ /// An internal representation of the Auto Selection.
+ /// </summary>
+ public static VideoLevel Auto = new VideoLevel("Auto", "auto");
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="VideoLevel"/> class.
+ /// </summary>
+ public VideoLevel()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="VideoLevel"/> class.
+ /// </summary>
+ /// <param name="displayName">
+ /// The display name.
+ /// </param>
+ /// <param name="shortName">
+ /// The short name.
+ /// </param>
+ public VideoLevel(string displayName, string shortName)
+ {
+ this.DisplayName = VideoLevelFactory.GetDisplayName(displayName);
+ this.ShortName = shortName;
+ }
+
+ /// <summary>
+ /// Gets or sets the display name.
+ /// </summary>
+ public string DisplayName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the short name.
+ /// </summary>
+ public string ShortName { get; set; }
+
+ /// <summary>
+ /// The clone.
+ /// </summary>
+ /// <returns>
+ /// The <see cref="VideoProfile"/>.
+ /// </returns>
+ public VideoLevel Clone()
+ {
+ return new VideoLevel(this.DisplayName, this.ShortName);
+ }
+
+ /// <summary>
+ /// The equals.
+ /// </summary>
+ /// <param name="other">
+ /// The other.
+ /// </param>
+ /// <returns>
+ /// The <see cref="bool"/>.
+ /// </returns>
+ protected bool Equals(VideoLevel other)
+ {
+ return string.Equals(this.ShortName, other.ShortName);
+ }
+
+ /// <summary>
+ /// The equals.
+ /// </summary>
+ /// <param name="obj">
+ /// The obj.
+ /// </param>
+ /// <returns>
+ /// The <see cref="bool"/>.
+ /// </returns>
+ 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);
+ }
+
+ /// <summary>
+ /// The get hash code.
+ /// </summary>
+ /// <returns>
+ /// The <see cref="int"/>.
+ /// </returns>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="VideoPreset.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>
+// The video preset.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models.Video
+{
+ using VideoPresetFactory = HandBrakeWPF.Services.Encode.Factories.VideoPresetFactory;
+
+ /// <summary>
+ /// The video preset.
+ /// </summary>
+ public class VideoPreset
+ {
+ /// <summary>
+ /// A built-in version of the "None" object.
+ /// </summary>
+ public static VideoPreset None = new VideoPreset("None", "none");
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="VideoPreset"/> class.
+ /// </summary>
+ public VideoPreset()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="VideoPreset"/> class.
+ /// </summary>
+ /// <param name="displayName">
+ /// The display name.
+ /// </param>
+ /// <param name="shortName">
+ /// The short name.
+ /// </param>
+ public VideoPreset(string displayName, string shortName)
+ {
+ this.DisplayName = VideoPresetFactory.GetDisplayName(displayName);
+ this.ShortName = shortName;
+ }
+
+ /// <summary>
+ /// Gets or sets the display name.
+ /// </summary>
+ public string DisplayName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the short name.
+ /// </summary>
+ public string ShortName { get; set; }
+
+ /// <summary>
+ /// The clone.
+ /// </summary>
+ /// <returns>
+ /// The <see cref="VideoProfile"/>.
+ /// </returns>
+ public VideoPreset Clone()
+ {
+ return new VideoPreset(this.DisplayName, this.ShortName);
+ }
+
+ /// <summary>
+ /// The equals.
+ /// </summary>
+ /// <param name="other">
+ /// The other.
+ /// </param>
+ /// <returns>
+ /// The <see cref="bool"/>.
+ /// </returns>
+ protected bool Equals(VideoPreset other)
+ {
+ return string.Equals(this.ShortName, other.ShortName);
+ }
+
+ /// <summary>
+ /// The equals.
+ /// </summary>
+ /// <param name="obj">
+ /// The obj.
+ /// </param>
+ /// <returns>
+ /// The <see cref="bool"/>.
+ /// </returns>
+ 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);
+ }
+
+ /// <summary>
+ /// The get hash code.
+ /// </summary>
+ /// <returns>
+ /// The <see cref="int"/>.
+ /// </returns>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="VideoProfile.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>
+// The video profile.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models.Video
+{
+ using VideoProfileFactory = HandBrakeWPF.Services.Encode.Factories.VideoProfileFactory;
+
+ /// <summary>
+ /// The video profile.
+ /// </summary>
+ public class VideoProfile
+ {
+ /// <summary>
+ /// An internal representation of the Auto Selection.
+ /// </summary>
+ public static VideoProfile Auto = new VideoProfile("Auto", "auto");
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="VideoProfile"/> class.
+ /// </summary>
+ public VideoProfile()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="VideoProfile"/> class.
+ /// </summary>
+ /// <param name="displayName">
+ /// The display name.
+ /// </param>
+ /// <param name="shortName">
+ /// The short name.
+ /// </param>
+ public VideoProfile(string displayName, string shortName)
+ {
+ this.DisplayName = VideoProfileFactory.GetDisplayName(displayName);
+ this.ShortName = shortName;
+ }
+
+ /// <summary>
+ /// Gets or sets the display name.
+ /// </summary>
+ public string DisplayName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the short name.
+ /// </summary>
+ public string ShortName { get; set; }
+
+ /// <summary>
+ /// The clone.
+ /// </summary>
+ /// <returns>
+ /// The <see cref="VideoProfile"/>.
+ /// </returns>
+ public VideoProfile Clone()
+ {
+ return new VideoProfile(this.DisplayName, this.ShortName);
+ }
+
+ /// <summary>
+ /// The equals.
+ /// </summary>
+ /// <param name="other">
+ /// The other.
+ /// </param>
+ /// <returns>
+ /// The <see cref="bool"/>.
+ /// </returns>
+ protected bool Equals(VideoProfile other)
+ {
+ return string.Equals(this.DisplayName, other.DisplayName) && string.Equals(this.ShortName, other.ShortName);
+ }
+
+ /// <summary>
+ /// The equals.
+ /// </summary>
+ /// <param name="obj">
+ /// The obj.
+ /// </param>
+ /// <returns>
+ /// The <see cref="bool"/>.
+ /// </returns>
+ 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);
+ }
+
+ /// <summary>
+ /// The get hash code.
+ /// </summary>
+ /// <returns>
+ /// The <see cref="int"/>.
+ /// </returns>
+ 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 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="VideoTune.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>
+// The video tune.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Encode.Model.Models.Video
+{
+ using VideoTuneFactory = HandBrakeWPF.Services.Encode.Factories.VideoTuneFactory;
+
+ /// <summary>
+ /// The video tune.
+ /// </summary>
+ public class VideoTune
+ {
+ /// <summary>
+ /// Static object to represent "None"
+ /// </summary>
+ public static VideoTune None = new VideoTune("None", "none");
+
+ /// <summary>
+ /// Static object to represent "None"
+ /// </summary>
+ public static VideoTune FastDecode = new VideoTune("Fast Decode", "fastdecode");
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="VideoTune"/> class.
+ /// </summary>
+ public VideoTune()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="VideoTune"/> class.
+ /// </summary>
+ /// <param name="displayName">
+ /// The display name.
+ /// </param>
+ /// <param name="shortName">
+ /// The short name.
+ /// </param>
+ public VideoTune(string displayName, string shortName)
+ {
+ this.DisplayName = VideoTuneFactory.GetDisplayName(displayName);
+ this.ShortName = shortName;
+ }
+
+ /// <summary>
+ /// Gets or sets the display name.
+ /// </summary>
+ public string DisplayName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the short name.
+ /// </summary>
+ public string ShortName { get; set; }
+
+ /// <summary>
+ /// The clone.
+ /// </summary>
+ /// <returns>
+ /// The <see cref="HandBrakeWPF.Services.Encode.Model.Models.Video.VideoProfile"/>.
+ /// </returns>
+ public VideoTune Clone()
+ {
+ return new VideoTune(this.DisplayName, this.ShortName);
+ }
+
+ /// <summary>
+ /// The equals.
+ /// </summary>
+ /// <param name="other">
+ /// The other.
+ /// </param>
+ /// <returns>
+ /// The <see cref="bool"/>.
+ /// </returns>
+ protected bool Equals(HandBrakeWPF.Services.Encode.Model.Models.Video.VideoProfile other)
+ {
+ return string.Equals(this.DisplayName, other.DisplayName) && string.Equals(this.ShortName, other.ShortName);
+ }
+
+ /// <summary>
+ /// The equals.
+ /// </summary>
+ /// <param name="other">
+ /// The other.
+ /// </param>
+ /// <returns>
+ /// The <see cref="bool"/>.
+ /// </returns>
+ protected bool Equals(VideoTune other)
+ {
+ return string.Equals(this.ShortName, other.ShortName);
+ }
+
+ /// <summary>
+ /// The equals.
+ /// </summary>
+ /// <param name="obj">
+ /// The obj.
+ /// </param>
+ /// <returns>
+ /// The <see cref="bool"/>.
+ /// </returns>
+ 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);
+ }
+
+ /// <summary>
+ /// The get hash code.
+ /// </summary>
+ /// <returns>
+ /// The <see cref="int"/>.
+ /// </returns>
+ public override int GetHashCode()
+ {
+ return (this.ShortName != null ? this.ShortName.GetHashCode() : 0);
+ }
+ }
+}