From 71c53a04fc0d43fee4ee024f854ebc6783234fd2 Mon Sep 17 00:00:00 2001 From: sr55 Date: Sun, 23 Feb 2014 15:43:16 +0000 Subject: WinGui: x265 UI patch by Zhang Zhigiang. This enables support for the x265 encoder from the GUI when paired with a build of HandBrake that has x265 enabled. Thanks git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6062 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- .../Factories/PlistPresetFactory.cs | 10 ++ .../Model/EncodeTask.cs | 28 +++- .../Model/Encoding/OutputFormat.cs | 3 + .../Utilities/Converters.cs | 97 +++++++++++ .../Utilities/InteropModelCreator.cs | 7 + .../Utilities/PlistUtility.cs | 4 + .../Utilities/QueryGeneratorUtility.cs | 37 +++++ .../Utilities/QueryParserUtility.cs | 36 +++- .../HandBrakeInterop/HandBrakeInterop.csproj | 3 + .../Model/Encoding/EncodingProfile.cs | 162 ++++++++++-------- .../Model/Encoding/VideoEncoder.cs | 6 +- .../Model/Encoding/x265/x265Preset.cs | 49 ++++++ .../Model/Encoding/x265/x265Profile.cs | 31 ++++ .../Model/Encoding/x265/x265Tune.cs | 28 ++++ .../Converters/Video/VideoEncoderConverter.cs | 5 + .../HandBrakeWPF/Properties/Resources.Designer.cs | 108 ++++++------ win/CS/HandBrakeWPF/Properties/Resources.resx | 12 +- win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs | 3 + win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs | 181 ++++++++++++++++++++- win/CS/HandBrakeWPF/Views/VideoView.xaml | 86 +++++++++- 20 files changed, 753 insertions(+), 143 deletions(-) create mode 100644 win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/x265/x265Preset.cs create mode 100644 win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/x265/x265Profile.cs create mode 100644 win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/x265/x265Tune.cs diff --git a/win/CS/HandBrake.ApplicationServices/Factories/PlistPresetFactory.cs b/win/CS/HandBrake.ApplicationServices/Factories/PlistPresetFactory.cs index fd10e22bd..e6b59c31d 100644 --- a/win/CS/HandBrake.ApplicationServices/Factories/PlistPresetFactory.cs +++ b/win/CS/HandBrake.ApplicationServices/Factories/PlistPresetFactory.cs @@ -20,6 +20,7 @@ namespace HandBrake.ApplicationServices.Factories using HandBrake.ApplicationServices.Utilities; using HandBrake.Interop.Model.Encoding; using HandBrake.Interop.Model.Encoding.x264; + using HandBrake.Interop.Model.Encoding.x265; /// /// A Factory to translate a Plist object into a Preset. @@ -237,6 +238,15 @@ namespace HandBrake.ApplicationServices.Factories case "QsvPreset": preset.Task.QsvPreset = EnumHelper.GetValue(kvp.Value, true); break; + case "h265Profile": + preset.Task.H265Profile = EnumHelper.GetValue(kvp.Value, true); + break; + case "x265Tune": + preset.Task.X265Tune = EnumHelper.GetValue(kvp.Value, true); + break; + case "x265Preset": + preset.Task.X265Preset = EnumHelper.GetValue(kvp.Value, true); + break; // Chapter Markers Tab case "ChapterMarkers": diff --git a/win/CS/HandBrake.ApplicationServices/Model/EncodeTask.cs b/win/CS/HandBrake.ApplicationServices/Model/EncodeTask.cs index b521d3b9d..6a519a382 100644 --- a/win/CS/HandBrake.ApplicationServices/Model/EncodeTask.cs +++ b/win/CS/HandBrake.ApplicationServices/Model/EncodeTask.cs @@ -18,6 +18,7 @@ namespace HandBrake.ApplicationServices.Model using HandBrake.Interop.Model; using HandBrake.Interop.Model.Encoding; using HandBrake.Interop.Model.Encoding.x264; + using HandBrake.Interop.Model.Encoding.x265; using OutputFormat = HandBrake.ApplicationServices.Model.Encoding.OutputFormat; @@ -55,6 +56,10 @@ namespace HandBrake.ApplicationServices.Model this.H264Profile = x264Profile.None; this.X264Tune = x264Tune.None; this.Modulus = 16; + + this.H265Profile = x265Profile.None; + this.X265Preset = x265Preset.VeryFast; + this.X265Tune = x265Tune.None; } /// @@ -137,11 +142,15 @@ namespace HandBrake.ApplicationServices.Model this.H264Level = task.H264Level; this.FastDecode = task.FastDecode; this.ExtraAdvancedArguments = task.ExtraAdvancedArguments; - + this.PreviewStartAt = task.PreviewStartAt; this.PreviewDuration = task.PreviewDuration; this.ShowAdvancedTab = task.ShowAdvancedTab; + + this.X265Preset = task.X265Preset; + this.X265Tune = task.X265Tune; + this.H265Profile = task.H265Profile; } #region Source @@ -457,6 +466,21 @@ namespace HandBrake.ApplicationServices.Model /// public string ExtraAdvancedArguments { get; set; } + /// + /// Gets or sets x265Preset. + /// + public x265Preset X265Preset { get; set; } + + /// + /// Gets or sets x265Profile. + /// + public x265Profile H265Profile { get; set; } + + /// + /// Gets or sets X265Tune. + /// + public x265Tune X265Tune { get; set; } + #endregion #region Preview @@ -484,7 +508,7 @@ namespace HandBrake.ApplicationServices.Model { if (this.OutputFormat == OutputFormat.M4V || this.OutputFormat == OutputFormat.Mp4) { - bool audio = this.AudioTracks.Any(item => item.Encoder == AudioEncoder.Ac3Passthrough || + 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); diff --git a/win/CS/HandBrake.ApplicationServices/Model/Encoding/OutputFormat.cs b/win/CS/HandBrake.ApplicationServices/Model/Encoding/OutputFormat.cs index 9323cc862..d9070de2f 100644 --- a/win/CS/HandBrake.ApplicationServices/Model/Encoding/OutputFormat.cs +++ b/win/CS/HandBrake.ApplicationServices/Model/Encoding/OutputFormat.cs @@ -24,5 +24,8 @@ namespace HandBrake.ApplicationServices.Model.Encoding [Description("MKV")] Mkv, + + [Description("X265")] + X265, } } diff --git a/win/CS/HandBrake.ApplicationServices/Utilities/Converters.cs b/win/CS/HandBrake.ApplicationServices/Utilities/Converters.cs index 9651c6e71..aa9842124 100644 --- a/win/CS/HandBrake.ApplicationServices/Utilities/Converters.cs +++ b/win/CS/HandBrake.ApplicationServices/Utilities/Converters.cs @@ -15,6 +15,7 @@ namespace HandBrake.ApplicationServices.Utilities using HandBrake.ApplicationServices.Model.Encoding; using HandBrake.Interop.Model.Encoding; using HandBrake.Interop.Model.Encoding.x264; + using HandBrake.Interop.Model.Encoding.x265; /// /// A class to convert various things to native C# objects @@ -296,6 +297,8 @@ namespace HandBrake.ApplicationServices.Utilities return VideoEncoder.QuickSync; case "theora": return VideoEncoder.Theora; + case "hevc": + return VideoEncoder.X265; default: return VideoEncoder.X264; } @@ -324,6 +327,8 @@ namespace HandBrake.ApplicationServices.Utilities return "qsv_h264"; case VideoEncoder.Theora: return "theora"; + case VideoEncoder.X265: + return "hevc"; default: return "x264"; } @@ -429,6 +434,94 @@ namespace HandBrake.ApplicationServices.Utilities #endregion + #region x265 + + /// + /// Get the x265Preset from a cli parameter + /// + /// + /// The preset. + /// + /// + /// The x265Preset enum value + /// + public static x265Preset Getx265PresetFromCli(string preset) + { + switch (preset) + { + case "ultrafast": + return x265Preset.Ultrafast; + case "superfast": + return x265Preset.Superfast; + case "veryfast": + return x265Preset.VeryFast; + case "faster": + return x265Preset.Faster; + case "fast": + return x265Preset.Fast; + case "medium": + return x265Preset.Medium; + case "slow": + return x265Preset.Slow; + case "slower": + return x265Preset.Slower; + case "veryslow": + return x265Preset.VerySlow; + case "placebo": + return x265Preset.Placebo; + default: + return x265Preset.Faster; + } + } + + /// + /// Get the x265 Profile from the cli + /// + /// + /// The preset. + /// + /// + /// The x265Profile enum value + /// + public static x265Profile Getx265ProfileFromCli(string profile) + { + switch (profile) + { + case "mainstillpicture": + return x265Profile.Mainstillpicture; + case "main": + return x265Profile.Main; + case "main10": + return x265Profile.Main10; + default: + return x265Profile.Main; + } + } + + /// + /// Get x265Tune enum from a cli string + /// + /// + /// The tune. + /// + /// + /// The x265Tune enum value + /// + public static x265Tune Getx265TuneFromCli(string tune) + { + switch (tune) + { + case "psnr": + return x265Tune.Psnr; + case "ssim": + return x265Tune.Ssim; + default: + return x265Tune.Psnr; + } + } + + #endregion + #region File Format /// @@ -450,6 +543,8 @@ namespace HandBrake.ApplicationServices.Utilities return OutputFormat.Mp4; case "mkv": return OutputFormat.Mkv; + case "x265": + return OutputFormat.X265; } } @@ -472,6 +567,8 @@ namespace HandBrake.ApplicationServices.Utilities return "m4v"; case OutputFormat.Mkv: return "mkv"; + case OutputFormat.X265: + return "x265"; } } diff --git a/win/CS/HandBrake.ApplicationServices/Utilities/InteropModelCreator.cs b/win/CS/HandBrake.ApplicationServices/Utilities/InteropModelCreator.cs index 67f243432..a4aacac7f 100644 --- a/win/CS/HandBrake.ApplicationServices/Utilities/InteropModelCreator.cs +++ b/win/CS/HandBrake.ApplicationServices/Utilities/InteropModelCreator.cs @@ -135,6 +135,9 @@ namespace HandBrake.ApplicationServices.Utilities case OutputFormat.Mkv: profile.ContainerName = "av_mkv"; // TODO make part of enum. break; + case OutputFormat.X265: + profile.ContainerName = "x265"; // TODO make part of enum. + break; } // Picture Settings @@ -196,6 +199,10 @@ namespace HandBrake.ApplicationServices.Utilities profile.X264Tunes.Add("fastdecode"); } + profile.X265Preset = work.X265Preset.ToString().ToLower().Replace(" ", string.Empty); + profile.X265Profile = work.H265Profile.ToString().ToLower().Replace(" ", string.Empty); + profile.X265Tunes = new List(); + // Chapter Markers profile.IncludeChapterMarkers = work.IncludeChapterMarkers; job.CustomChapterNames = work.ChapterNames.Select(item => item.ChapterName).ToList(); diff --git a/win/CS/HandBrake.ApplicationServices/Utilities/PlistUtility.cs b/win/CS/HandBrake.ApplicationServices/Utilities/PlistUtility.cs index 25c3a1426..7448f4bc5 100644 --- a/win/CS/HandBrake.ApplicationServices/Utilities/PlistUtility.cs +++ b/win/CS/HandBrake.ApplicationServices/Utilities/PlistUtility.cs @@ -281,6 +281,10 @@ namespace HandBrake.ApplicationServices.Utilities AddEncodeElement(xmlWriter, "x264UseAdvancedOptions", "integer", parsed.ShowAdvancedTab ? "1" : "0"); AddEncodeElement(xmlWriter, "qsvPreset", "string", parsed.QsvPreset.ToString().ToLower()); + AddEncodeElement(xmlWriter, "h265Profile", "string", parsed.H265Profile.ToString().ToLower()); + AddEncodeElement(xmlWriter, "x265Preset", "string", parsed.X265Preset.ToString().ToLower()); + AddEncodeElement(xmlWriter, "x265Tune", "string", parsed.X265Tune.ToString().ToLower()); + int videoQualityType = 0; if (parsed.VideoBitrate != null) videoQualityType = 1; else if (parsed.Quality != null) videoQualityType = 2; diff --git a/win/CS/HandBrake.ApplicationServices/Utilities/QueryGeneratorUtility.cs b/win/CS/HandBrake.ApplicationServices/Utilities/QueryGeneratorUtility.cs index b1db2fcaa..8b246b58c 100644 --- a/win/CS/HandBrake.ApplicationServices/Utilities/QueryGeneratorUtility.cs +++ b/win/CS/HandBrake.ApplicationServices/Utilities/QueryGeneratorUtility.cs @@ -22,6 +22,7 @@ namespace HandBrake.ApplicationServices.Utilities using HandBrake.ApplicationServices.Services.Interfaces; using HandBrake.Interop.Model.Encoding; using HandBrake.Interop.Model.Encoding.x264; + using HandBrake.Interop.Model.Encoding.x265; /// /// Generate a CLI Query for HandBrakeCLI @@ -435,6 +436,9 @@ namespace HandBrake.ApplicationServices.Utilities default: query += " -e x264"; break; + case VideoEncoder.X265: + query += " -e x265"; + break; } switch (task.VideoEncodeRateType) @@ -457,6 +461,9 @@ namespace HandBrake.ApplicationServices.Utilities case VideoEncoder.Theora: query += string.Format(" -q {0}", task.Quality.Value.ToString(CultureInfo.InvariantCulture)); break; + case VideoEncoder.X265: + query += string.Format(" -q {0}", task.Quality.Value.ToString(CultureInfo.InvariantCulture)); + break; } break; } @@ -937,6 +944,36 @@ namespace HandBrake.ApplicationServices.Utilities } } + // X265 Only + if (task.VideoEncoder == VideoEncoder.X265) + { + if (!task.ShowAdvancedTab) + { + if (task.X265Preset != x265Preset.VeryFast) + { + query += string.Format( + " --x265-preset={0} ", task.X265Preset.ToString().ToLower().Replace(" ", string.Empty)); + } + + if (task.X265Tune != x265Tune.None) + { + query += string.Format( + " --x265-tune=\"{0}\" ", task.X265Tune.ToString().ToLower().Replace(" ", string.Empty)); + } + + if (task.H265Profile != x265Profile.None) + { + query += string.Format( + " --h265-profile={0} ", task.H265Profile.ToString().ToLower().Replace(" ", string.Empty)); + } + + if (!string.IsNullOrEmpty(task.ExtraAdvancedArguments)) + { + query += string.Format(" -x {0}", task.ExtraAdvancedArguments); + } + } + } + // QSV Only if (task.VideoEncoder == VideoEncoder.QuickSync) { diff --git a/win/CS/HandBrake.ApplicationServices/Utilities/QueryParserUtility.cs b/win/CS/HandBrake.ApplicationServices/Utilities/QueryParserUtility.cs index 4872d6e7d..a3cfae6fe 100644 --- a/win/CS/HandBrake.ApplicationServices/Utilities/QueryParserUtility.cs +++ b/win/CS/HandBrake.ApplicationServices/Utilities/QueryParserUtility.cs @@ -115,6 +115,9 @@ namespace HandBrake.ApplicationServices.Utilities Match x264Profile = Regex.Match(input, @"--x264-profile([=a-zA-Z0-9\s ]*)"); Match h264Level = Regex.Match(input, @"--h264-level([=a-zA-Z0-9.\s ]*)"); + Match x265Profile = Regex.Match(input, @"--x265-profile([=a-zA-Z0-9\s ]*)"); + Match x265Tune = Regex.Match(input, @"--x265-tune([=,a-zA-Z0-9\s ]*)"); + Match x265Preset = Regex.Match(input, @"--x265-preset([=a-zA-Z0-9\s ]*)"); #endregion #region Set Varibles @@ -476,7 +479,38 @@ namespace HandBrake.ApplicationServices.Utilities parsed.X264Tune = Converters.Getx264TuneFromCli(tuneOptions); } - + + + + + + + if (x265Preset.Success) + parsed.X265Preset = + Converters.Getx265PresetFromCli(x265Preset.ToString().Replace("--x265-preset", string.Empty).Replace("=", string.Empty).Trim()); + + if (h264Profile.Success) + parsed.H265Profile = + Converters.Getx265ProfileFromCli(h264Profile.ToString().Replace("--h265-profile", string.Empty).Replace("=", string.Empty).Trim()); + + if (x265Profile.Success) + parsed.H265Profile = + Converters.Getx265ProfileFromCli(x265Profile.ToString().Replace("--x265-profile", string.Empty).Replace("=", string.Empty).Trim()); + + if (x265Tune.Success) + { + string tuneOptions = + x265Tune.ToString().Replace("--x265-tune", string.Empty).Replace("=", string.Empty).Trim(); + + parsed.FastDecode = tuneOptions.Contains("fastdecode"); + + // Remove these options. They are not in the dropdown. + tuneOptions = tuneOptions.Replace("fastdecode", string.Empty).Replace( + ",", string.Empty); + + parsed.X265Tune = Converters.Getx265TuneFromCli(tuneOptions); + } + #endregion } catch (Exception exc) diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeInterop.csproj b/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeInterop.csproj index b6e60faad..bb4bd48cf 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeInterop.csproj +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/HandBrakeInterop.csproj @@ -151,6 +151,9 @@ + + + diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/EncodingProfile.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/EncodingProfile.cs index f37766281..c1947745b 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/EncodingProfile.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/EncodingProfile.cs @@ -11,20 +11,20 @@ namespace HandBrake.Interop.Model.Encoding { using System.Collections.Generic; - using HandBrake.Interop.Model; + using HandBrake.Interop.Model; /// /// The encoding profile. /// public class EncodingProfile - { + { /// /// Initializes a new instance of the class. /// public EncodingProfile() - { - this.Cropping = new Cropping(); - } + { + this.Cropping = new Cropping(); + } #region Destination and Output Settings @@ -212,6 +212,26 @@ namespace HandBrake.Interop.Model.Encoding /// public List X264Tunes { get; set; } + /// + /// Gets or sets the x 265 profile. + /// + public string X265Profile { get; set; } + + /// + /// Gets or sets the x 265 preset. + /// + public string X265Preset { get; set; } + + /// + /// Gets or sets the x 265 tunes. + /// + public List X265Tunes { get; set; } + + /// + /// Gets or sets the x 265 level. + /// + public List X265Level { get; set; } + /// /// Gets or sets the qsv preset. /// @@ -282,70 +302,70 @@ namespace HandBrake.Interop.Model.Encoding #endregion /// - /// The clone. - /// - /// - /// The . - /// - public EncodingProfile Clone() - { - var profile = new EncodingProfile - { - ContainerName = this.ContainerName, - PreferredExtension = this.PreferredExtension, - IncludeChapterMarkers = this.IncludeChapterMarkers, - LargeFile = this.LargeFile, - Optimize = this.Optimize, - IPod5GSupport = this.IPod5GSupport, - - Width = this.Width, - Height = this.Height, - MaxWidth = this.MaxWidth, - MaxHeight = this.MaxHeight, - ScaleMethod = this.ScaleMethod, - CroppingType = this.CroppingType, - Cropping = this.Cropping.Clone(), - Anamorphic = this.Anamorphic, - UseDisplayWidth = this.UseDisplayWidth, - DisplayWidth = this.DisplayWidth, - KeepDisplayAspect = this.KeepDisplayAspect, - PixelAspectX = this.PixelAspectX, - PixelAspectY = this.PixelAspectY, - Modulus = this.Modulus, - - Deinterlace = this.Deinterlace, - CustomDeinterlace = this.CustomDeinterlace, - Decomb = this.Decomb, - CustomDecomb = this.CustomDecomb, - Detelecine = this.Detelecine, - CustomDetelecine = this.CustomDetelecine, - Denoise = this.Denoise, - CustomDenoise = this.CustomDenoise, - Deblock = this.Deblock, - Grayscale = this.Grayscale, - - VideoEncoder = this.VideoEncoder, - X264Options = this.X264Options, - X264Profile = this.X264Profile, - X264Preset = this.X264Preset, - X264Tunes = this.X264Tunes, - QsvPreset = this.QsvPreset, - QsvDecode = this.QsvDecode, - H264Level = this.H264Level, - VideoEncodeRateType = this.VideoEncodeRateType, - Quality = this.Quality, - TargetSize = this.TargetSize, - VideoBitrate = this.VideoBitrate, - TwoPass = this.TwoPass, - TurboFirstPass = this.TurboFirstPass, - Framerate = this.Framerate, - ConstantFramerate = this.ConstantFramerate, - - AudioEncodings = new List(this.AudioEncodings), - AudioEncoderFallback = this.AudioEncoderFallback - }; - - return profile; - } - } + /// The clone. + /// + /// + /// The . + /// + public EncodingProfile Clone() + { + var profile = new EncodingProfile + { + ContainerName = this.ContainerName, + PreferredExtension = this.PreferredExtension, + IncludeChapterMarkers = this.IncludeChapterMarkers, + LargeFile = this.LargeFile, + Optimize = this.Optimize, + IPod5GSupport = this.IPod5GSupport, + + Width = this.Width, + Height = this.Height, + MaxWidth = this.MaxWidth, + MaxHeight = this.MaxHeight, + ScaleMethod = this.ScaleMethod, + CroppingType = this.CroppingType, + Cropping = this.Cropping.Clone(), + Anamorphic = this.Anamorphic, + UseDisplayWidth = this.UseDisplayWidth, + DisplayWidth = this.DisplayWidth, + KeepDisplayAspect = this.KeepDisplayAspect, + PixelAspectX = this.PixelAspectX, + PixelAspectY = this.PixelAspectY, + Modulus = this.Modulus, + + Deinterlace = this.Deinterlace, + CustomDeinterlace = this.CustomDeinterlace, + Decomb = this.Decomb, + CustomDecomb = this.CustomDecomb, + Detelecine = this.Detelecine, + CustomDetelecine = this.CustomDetelecine, + Denoise = this.Denoise, + CustomDenoise = this.CustomDenoise, + Deblock = this.Deblock, + Grayscale = this.Grayscale, + + VideoEncoder = this.VideoEncoder, + X264Options = this.X264Options, + X264Profile = this.X264Profile, + X264Preset = this.X264Preset, + X264Tunes = this.X264Tunes, + QsvPreset = this.QsvPreset, + QsvDecode = this.QsvDecode, + H264Level = this.H264Level, + VideoEncodeRateType = this.VideoEncodeRateType, + Quality = this.Quality, + TargetSize = this.TargetSize, + VideoBitrate = this.VideoBitrate, + TwoPass = this.TwoPass, + TurboFirstPass = this.TurboFirstPass, + Framerate = this.Framerate, + ConstantFramerate = this.ConstantFramerate, + + AudioEncodings = new List(this.AudioEncodings), + AudioEncoderFallback = this.AudioEncoderFallback + }; + + return profile; + } + } } diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/VideoEncoder.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/VideoEncoder.cs index b355d5038..7e30009b7 100644 --- a/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/VideoEncoder.cs +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/VideoEncoder.cs @@ -35,6 +35,10 @@ namespace HandBrake.Interop.Model.Encoding [Display(Name = "VP3 (Theora)")] [ShortName("theora")] - Theora + Theora, + + [Display(Name = "H.265 (x265)")] + [ShortName("hvec")] + X265 } } diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/x265/x265Preset.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/x265/x265Preset.cs new file mode 100644 index 000000000..f8ec669d5 --- /dev/null +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/x265/x265Preset.cs @@ -0,0 +1,49 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Defines the x265Preset type. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrake.Interop.Model.Encoding.x265 +{ + using System.ComponentModel.DataAnnotations; + + /// + /// The X265 Preset + /// + public enum x265Preset + { + [Display(Name = "Ultrafast")] + Ultrafast, + + [Display(Name = "Super Fast")] + Superfast, + + [Display(Name = "Very Fast")] + VeryFast, + + [Display(Name = "Faster")] + Faster, + + [Display(Name = "Fast")] + Fast, + + [Display(Name = "Medium")] + Medium, + + [Display(Name = "Slow")] + Slow, + + [Display(Name = "Slower")] + Slower, + + [Display(Name = "Very Slow")] + VerySlow, + + [Display(Name = "Placebo")] + Placebo, + } +} \ No newline at end of file diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/x265/x265Profile.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/x265/x265Profile.cs new file mode 100644 index 000000000..8d3aab3da --- /dev/null +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/x265/x265Profile.cs @@ -0,0 +1,31 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// The X265 Profile +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrake.Interop.Model.Encoding.x265 +{ + using System.ComponentModel.DataAnnotations; + + /// + /// The X265 Profile + /// + public enum x265Profile + { + [Display(Name = "Auto")] + None = 0, + + [Display(Name = "Main")] + Main, + + [Display(Name = "Main10")] + Main10, + + [Display(Name = "Mainstillpicture")] + Mainstillpicture, + } +} \ No newline at end of file diff --git a/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/x265/x265Tune.cs b/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/x265/x265Tune.cs new file mode 100644 index 000000000..03d762359 --- /dev/null +++ b/win/CS/HandBrake.Interop/HandBrakeInterop/Model/Encoding/x265/x265Tune.cs @@ -0,0 +1,28 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Defines the x265Tune type. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrake.Interop.Model.Encoding.x265 +{ + using System.ComponentModel.DataAnnotations; + + /// + /// The X265 Tune MOdel + /// + public enum x265Tune + { + [Display(Name = "None")] + None = 0, + + [Display(Name = "PSNR")] + Psnr, + + [Display(Name = "SSIM")] + Ssim, + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs b/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs index 8e2f1d379..6854656d4 100644 --- a/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs +++ b/win/CS/HandBrakeWPF/Converters/Video/VideoEncoderConverter.cs @@ -60,6 +60,11 @@ namespace HandBrakeWPF.Converters.Video encoders.Remove(VideoEncoder.QuickSync); } + if (task != null && task.OutputFormat != OutputFormat.X265) + { + encoders.Remove(VideoEncoder.X265); + } + return EnumHelper.GetEnumDisplayValuesSubset(encoders); } diff --git a/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs b/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs index 45a63951a..2eca4f527 100644 --- a/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs +++ b/win/CS/HandBrakeWPF/Properties/Resources.Designer.cs @@ -792,6 +792,60 @@ namespace HandBrakeWPF.Properties { } } + /// + /// Looks up a localized string similar to The full list of encoder parameters: + ///{0}. + /// + public static string Video_EncoderExtraArgs { + get { + return ResourceManager.GetString("Video_EncoderExtraArgs", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sets and ensures compliance with the specified H.264 Levels. This will override all other settings.. + /// + public static string Video_EncoderLevel { + get { + return ResourceManager.GetString("Video_EncoderLevel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Adjusts x264 settings to trade off compression efficiency against encoding speed. + /// + ///This establishes your default x264 settings. Tunes, profiles, levels and advanced options string will be applied to this. + /// + ///You should generally set this option to the slowest you can bear since slower settings will result in better quality or smaller files.. + /// + public static string Video_EncoderPreset { + get { + return ResourceManager.GetString("Video_EncoderPreset", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Limit the H.264 profile of the output stream. This will override all other settings.. + /// + public static string Video_EncoderProfile { + get { + return ResourceManager.GetString("Video_EncoderProfile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tune settings to optimise for common scenarios + /// + ///This can improve efficiency for particular source characteristics or set of characteristics of the output file. + /// + ///Changes will be applied after the preset but before all other parameters.. + /// + public static string Video_EncoderTune { + get { + return ResourceManager.GetString("Video_EncoderTune", resourceCulture); + } + } + /// /// Looks up a localized string similar to Higher Quality |. /// @@ -884,16 +938,6 @@ namespace HandBrakeWPF.Properties { } } - /// - /// Looks up a localized string similar to The full x264 list of parameters: - ///{0}. - /// - public static string Video_x264ExtraArgs { - get { - return ResourceManager.GetString("Video_x264ExtraArgs", resourceCulture); - } - } - /// /// Looks up a localized string similar to Reduce decoder CPU usage. /// @@ -905,50 +949,6 @@ namespace HandBrakeWPF.Properties { } } - /// - /// Looks up a localized string similar to Sets and ensures compliance with the specified H.264 Levels. This will override all other settings.. - /// - public static string Video_x264Level { - get { - return ResourceManager.GetString("Video_x264Level", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Adjusts x264 settings to trade off compression efficiency against encoding speed. - /// - ///This establishes your default x264 settings. Tunes, profiles, levels and advanced options string will be applied to this. - /// - ///You should generally set this option to the slowest you can bear since slower settings will result in better quality or smaller files.. - /// - public static string Video_x264Preset { - get { - return ResourceManager.GetString("Video_x264Preset", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Limit the H.264 profile of the output stream. This will override all other settings.. - /// - public static string Video_x264Profile { - get { - return ResourceManager.GetString("Video_x264Profile", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Tune settings to optimise for common scenarios - /// - ///This can improve efficiency for particular source characteristics or set of characteristics of the output file. - /// - ///Changes will be applied after the preset but before all other parameters.. - /// - public static string Video_x264Tune { - get { - return ResourceManager.GetString("Video_x264Tune", resourceCulture); - } - } - /// /// Looks up a localized string similar to Warning. /// diff --git a/win/CS/HandBrakeWPF/Properties/Resources.resx b/win/CS/HandBrakeWPF/Properties/Resources.resx index d86c6cc5b..2f323b50e 100644 --- a/win/CS/HandBrakeWPF/Properties/Resources.resx +++ b/win/CS/HandBrakeWPF/Properties/Resources.resx @@ -233,8 +233,8 @@ Baseline profile, as required for iPods and similar devices, requires weighted P Note that some devices and players, even those that support Main Profile, may have problems with Weighted P-frame prediction: the Apple TV is completely incompatible with it, for example. - - The full x264 list of parameters: + + The full list of encoder parameters: {0} @@ -242,20 +242,20 @@ may have problems with Weighted P-frame prediction: the Apple TV is completely i Set this if your device is struggling to play the output. (i.e. dropped frames) - + Sets and ensures compliance with the specified H.264 Levels. This will override all other settings. - + Adjusts x264 settings to trade off compression efficiency against encoding speed. This establishes your default x264 settings. Tunes, profiles, levels and advanced options string will be applied to this. You should generally set this option to the slowest you can bear since slower settings will result in better quality or smaller files. - + Limit the H.264 profile of the output stream. This will override all other settings. - + Tune settings to optimise for common scenarios This can improve efficiency for particular source characteristics or set of characteristics of the output file. diff --git a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs index d9c2640f8..4306fc7f7 100644 --- a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs @@ -1440,6 +1440,9 @@ namespace HandBrakeWPF.ViewModels case ".m4v": this.SelectedOutputFormat = OutputFormat.M4V; break; + case ".x265": + this.SelectedOutputFormat = OutputFormat.X265; + break; } this.NotifyOfPropertyChange(() => this.CurrentTask); diff --git a/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs index 5dd4b07aa..0d3dc5ce0 100644 --- a/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/VideoViewModel.cs @@ -25,6 +25,7 @@ namespace HandBrakeWPF.ViewModels using HandBrake.Interop; using HandBrake.Interop.Model.Encoding; using HandBrake.Interop.Model.Encoding.x264; + using HandBrake.Interop.Model.Encoding.x265; using HandBrakeWPF.Commands.Interfaces; using HandBrakeWPF.Properties; @@ -45,7 +46,7 @@ namespace HandBrakeWPF.ViewModels /// /// The possible h264 levels. /// - private static readonly List Levels = new List { "Auto", "1.0", "1b", "1.1", "1.2", "1.3", "2.0", "2.1", "2.2", "3.0", "3.1", "3.2", "4.0", "4.1", "4.2", "5.0", "5.1", "5.2"}; + private static readonly List Levels = new List { "Auto", "1.0", "1b", "1.1", "1.2", "1.3", "2.0", "2.1", "2.2", "3.0", "3.1", "3.2", "4.0", "4.1", "4.2", "5.0", "5.1", "5.2" }; /// /// Backing field for the user setting service. @@ -62,6 +63,11 @@ namespace HandBrakeWPF.ViewModels /// private bool displayX264Options; + /// + /// Backing field used to display / hide the x265 options + /// + private bool displayX265Options; + /// /// The display qsv options. /// @@ -122,6 +128,11 @@ namespace HandBrakeWPF.ViewModels /// private bool displayNonQSVControls; + /// + /// The x265 preset value. + /// + private int x265PresetValue; + #endregion #region Constructors and Destructors @@ -151,6 +162,10 @@ namespace HandBrakeWPF.ViewModels X264Tunes = EnumHelper.GetEnumList().Where(t => t != x264Tune.Fastdecode); this.H264Levels = Levels; + X265Presets = new BindingList(EnumHelper.GetEnumList().ToList()); + H265Profiles = EnumHelper.GetEnumList(); + X265Tunes = EnumHelper.GetEnumList(); + this.userSettingService.SettingChanged += this.UserSettingServiceSettingChanged; } @@ -400,6 +415,9 @@ namespace HandBrakeWPF.ViewModels case VideoEncoder.Theora: Task.Quality = value; break; + case VideoEncoder.X265: + Task.Quality = value; + break; } this.NotifyOfPropertyChange(() => this.RF); @@ -539,6 +557,10 @@ namespace HandBrakeWPF.ViewModels // Hide the x264 controls when not needed. this.DisplayX264Options = value == VideoEncoder.X264; + + // Hide the x265 controls when not needed. + this.DisplayX265Options = value == VideoEncoder.X265; + this.DisplayQSVOptions = value == VideoEncoder.QuickSync; this.DisplayH264Options = value == VideoEncoder.X264 || value == VideoEncoder.QuickSync; this.UseAdvancedTab = value != VideoEncoder.QuickSync && this.UseAdvancedTab; @@ -599,7 +621,7 @@ namespace HandBrakeWPF.ViewModels } } } - + /// /// Gets or sets a value indicating whether to display H264 /// @@ -633,6 +655,23 @@ namespace HandBrakeWPF.ViewModels } } + /// + /// Gets or sets a value indicating whether display x 264 options. + /// + public bool DisplayX265Options + { + get + { + return this.displayX265Options; + } + set + { + this.displayX265Options = value; + this.NotifyOfPropertyChange(() => this.DisplayX265Options); + this.NotifyOfPropertyChange(() => FullOptionsTooltip); + } + } + /// /// Gets or sets a value indicating whether to display qsv options. /// @@ -707,7 +746,7 @@ namespace HandBrakeWPF.ViewModels } } } - + /// /// Gets or sets X264Preset. /// @@ -864,7 +903,7 @@ namespace HandBrakeWPF.ViewModels { get { - return string.Format(Resources.Video_x264ExtraArgs, this.GetActualx264Query()); // "You can provide additional arguments using the standard x264 format"; + return string.Format(Resources.Video_EncoderExtraArgs, this.GetActualx264Query()); // "You can provide additional arguments using the standard x264 format"; } } @@ -879,6 +918,106 @@ namespace HandBrakeWPF.ViewModels } } + /// + /// Gets or sets the x 265 preset value. + /// + public int X265PresetValue + { + get + { + return this.x265PresetValue; + } + set + { + if (!object.Equals(this.X265PresetValue, value)) + { + this.x265PresetValue = value; + this.X265Preset = this.X265Presets[value]; + this.NotifyOfPropertyChange(() => this.x265PresetValue); + this.NotifyOfPropertyChange(() => FullOptionsTooltip); + } + } + } + + /// + /// Gets or sets X265Preset. + /// + public x265Preset X265Preset + { + get + { + return this.Task.X265Preset; + } + set + { + if (!object.Equals(this.X265Preset, value)) + { + this.Task.X265Preset = value; + this.NotifyOfPropertyChange(() => this.X265Preset); + ResetAdvancedTab(); + this.NotifyOfPropertyChange(() => FullOptionsTooltip); + } + } + } + + + /// + /// Gets or sets H265Profile. + /// + public x265Profile H265Profile + { + get + { + return this.Task.H265Profile; + } + + set + { + if (!object.Equals(this.H265Profile, value)) + { + this.Task.H265Profile = value; + this.NotifyOfPropertyChange(() => this.H265Profile); + ResetAdvancedTab(); + this.NotifyOfPropertyChange(() => FullOptionsTooltip); + } + } + } + + /// + /// Gets or sets X265Tune. + /// + public x265Tune X265Tune + { + get + { + return this.Task.X265Tune; + } + set + { + if (!object.Equals(this.X265Tune, value)) + { + this.Task.X265Tune = value; + this.NotifyOfPropertyChange(() => this.X265Tune); + ResetAdvancedTab(); + this.NotifyOfPropertyChange(() => FullOptionsTooltip); + } + } + } + + /// + /// Gets or sets X265Presets. + /// + public BindingList X265Presets { get; set; } + + /// + /// Gets or sets X265Profiles. + /// + public IEnumerable H265Profiles { get; set; } + + /// + /// Gets or sets X265Tunes. + /// + public IEnumerable X265Tunes { get; set; } #endregion #region Public Methods @@ -970,6 +1109,13 @@ namespace HandBrakeWPF.ViewModels this.RF = (int)preset.Task.Quality.Value; } break; + + case VideoEncoder.X265: + if (preset.Task.Quality.HasValue) + { + this.RF = (int)preset.Task.Quality.Value; + } + break; } this.Task.TwoPass = preset.Task.TwoPass; @@ -1009,6 +1155,20 @@ namespace HandBrakeWPF.ViewModels this.FastDecode = false; } + // x265 Only + if (preset.Task.VideoEncoder == VideoEncoder.X265) + { + this.X265PresetValue = (int)preset.Task.X264Preset; + this.X265Tune = preset.Task.X265Tune; + this.H265Profile = preset.Task.H265Profile; + } + else + { + this.X265PresetValue = (int)x265Preset.VeryFast; + this.X265Tune = x265Tune.None; + this.H265Profile = x265Profile.None; + } + // QSV Only if (preset.Task.VideoEncoder == VideoEncoder.QuickSync) { @@ -1054,6 +1214,10 @@ namespace HandBrakeWPF.ViewModels this.NotifyOfPropertyChange(() => this.FastDecode); this.NotifyOfPropertyChange(() => this.ExtraArguments); this.NotifyOfPropertyChange(() => this.QsvPreset); + + this.NotifyOfPropertyChange(() => this.H265Profile); + this.NotifyOfPropertyChange(() => this.X265Preset); + this.NotifyOfPropertyChange(() => this.X265Tune); } /// @@ -1067,6 +1231,7 @@ namespace HandBrakeWPF.ViewModels this.DisplayH264Options = encoder == VideoEncoder.X264 || encoder == VideoEncoder.QuickSync; this.DisplayX264Options = encoder == VideoEncoder.X264; this.DisplayQSVOptions = encoder == VideoEncoder.QuickSync; + this.DisplayX265Options = encoder == VideoEncoder.X265; if (encoder == VideoEncoder.QuickSync) { @@ -1100,6 +1265,10 @@ namespace HandBrakeWPF.ViewModels this.H264Level = "Auto"; this.ExtraArguments = string.Empty; this.canClear = true; + + this.H265Profile = x265Profile.None; + this.x265PresetValue = 1; + this.X265Tune = x265Tune.None; } /// @@ -1135,6 +1304,10 @@ namespace HandBrakeWPF.ViewModels this.QualityMin = 0; this.QualityMax = 63; break; + case VideoEncoder.X265: + this.QualityMin = 0; + this.QualityMax = 50; + break; } } diff --git a/win/CS/HandBrakeWPF/Views/VideoView.xaml b/win/CS/HandBrakeWPF/Views/VideoView.xaml index 1f0b31764..a7b87a3a7 100644 --- a/win/CS/HandBrakeWPF/Views/VideoView.xaml +++ b/win/CS/HandBrakeWPF/Views/VideoView.xaml @@ -170,7 +170,7 @@ @@ -181,7 +181,7 @@ ItemsSource="{Binding X264Tunes, Converter={StaticResource enumComboConverter}}" SelectedItem="{Binding X264Tune, Converter={StaticResource enumComboConverter}}" Visibility="{Binding DisplayX264Options, Converter={StaticResource boolToVisConverter}}" - ToolTip="{x:Static Properties:Resources.Video_x264Tune}" + ToolTip="{x:Static Properties:Resources.Video_EncoderTune}" Style="{StaticResource LongToolTipHolder}" /> + ToolTip="{x:Static Properties:Resources.Video_EncoderProfile}" /> + ToolTip="{x:Static Properties:Resources.Video_EncoderLevel}"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3