From 515f8070a43f25de58019314bf6893c12a478c76 Mon Sep 17 00:00:00 2001 From: sr55 Date: Sat, 21 Sep 2013 17:47:12 +0000 Subject: WinGui: Fix up libhb encode feature. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@5790 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- .../Isolation/IsolatedEncodeService.cs | 25 ++++ .../Services/Encode.cs | 33 +++++ .../Services/Interfaces/IEncode.cs | 15 ++ .../Services/LibEncode.cs | 140 ++++++++++++------ .../Services/LibScan.cs | 1 - .../Services/ServerService.cs | 5 +- .../Utilities/InteropModelCreator.cs | 163 +++++++++++---------- 7 files changed, 260 insertions(+), 122 deletions(-) (limited to 'win/CS/HandBrake.ApplicationServices') diff --git a/win/CS/HandBrake.ApplicationServices/Isolation/IsolatedEncodeService.cs b/win/CS/HandBrake.ApplicationServices/Isolation/IsolatedEncodeService.cs index 31c1d8cec..2f29d7054 100644 --- a/win/CS/HandBrake.ApplicationServices/Isolation/IsolatedEncodeService.cs +++ b/win/CS/HandBrake.ApplicationServices/Isolation/IsolatedEncodeService.cs @@ -92,6 +92,17 @@ namespace HandBrake.ApplicationServices.Isolation } } + /// + /// Gets a value indicating whether can pause. + /// + public bool CanPause + { + get + { + return false; // TODO make this work. + } + } + /// /// Gets a value indicating whether IsEncoding. /// @@ -171,6 +182,20 @@ namespace HandBrake.ApplicationServices.Isolation delegate { this.Service.StartEncode(job, enableLogging); }); } + /// + /// The pause. + /// + public void Pause() + { + } + + /// + /// The resume. + /// + public void Resume() + { + } + /// /// Kill the CLI process /// diff --git a/win/CS/HandBrake.ApplicationServices/Services/Encode.cs b/win/CS/HandBrake.ApplicationServices/Services/Encode.cs index 4779d353e..806c08fa5 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/Encode.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/Encode.cs @@ -74,6 +74,17 @@ namespace HandBrake.ApplicationServices.Services /// protected Process HbProcess { get; set; } + /// + /// Gets a value indicating whether can pause. + /// + public bool CanPause + { + get + { + return false; + } + } + #endregion #region Public Methods @@ -201,6 +212,28 @@ namespace HandBrake.ApplicationServices.Services } } + /// + /// The pause. + /// + /// + /// This feature is not available for CLI based encoding. + /// + public void Pause() + { + throw new NotImplementedException("This feature is not available for CLI based encoding."); + } + + /// + /// The resume. + /// + /// + /// This feature is not available for CLI based encoding. + /// + public void Resume() + { + throw new NotImplementedException("This feature is not available for CLI based encoding."); + } + /// /// Kill the CLI process /// diff --git a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IEncode.cs b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IEncode.cs index fbb59ec2b..8d70247f7 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IEncode.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IEncode.cs @@ -71,6 +71,11 @@ namespace HandBrake.ApplicationServices.Services.Interfaces /// int LogIndex { get; } + /// + /// Gets a value indicating whether can pause. + /// + bool CanPause { get; } + /// /// Start with a LibHb EncodeJob Object /// @@ -82,6 +87,16 @@ namespace HandBrake.ApplicationServices.Services.Interfaces /// void Start(QueueTask job, bool enableLogging); + /// + /// The pause. + /// + void Pause(); + + /// + /// The resume. + /// + void Resume(); + /// /// Kill the CLI process /// diff --git a/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs b/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs index f7247f6cf..f6da448ac 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs @@ -42,14 +42,14 @@ namespace HandBrake.ApplicationServices.Services private readonly IUserSettingService userSettingService; /// - /// The Start time of the current Encode; + /// The instance. /// - private DateTime startTime; + private IHandBrakeInstance instance; /// - /// An Instance of the HandBrake Interop Library + /// The Start time of the current Encode; /// - private IHandBrakeInstance instance; + private DateTime startTime; /// /// A flag to indicate if logging is enabled or not. @@ -69,23 +69,26 @@ namespace HandBrake.ApplicationServices.Services /// /// The user Setting Service. /// - /// - /// The hand Brake Instance. - /// - public LibEncode(IUserSettingService userSettingService, IHandBrakeInstance handBrakeInstance) + public LibEncode(IUserSettingService userSettingService) : base(userSettingService) { this.userSettingService = userSettingService; - // Setup the HandBrake Instance - this.instance = handBrakeInstance; - this.instance.EncodeCompleted += this.InstanceEncodeCompleted; - this.instance.EncodeProgress += this.InstanceEncodeProgress; - HandBrakeUtils.MessageLogged += this.HandBrakeInstanceMessageLogged; HandBrakeUtils.ErrorLogged += this.HandBrakeInstanceErrorLogged; } + /// + /// Gets a value indicating whether can pause. + /// + public bool CanPause + { + get + { + return true; + } + } + /// /// Start with a LibHb EncodeJob Object /// @@ -97,10 +100,18 @@ namespace HandBrake.ApplicationServices.Services /// public void Start(QueueTask job, bool enableLogging) { + // Setup this.startTime = DateTime.Now; this.loggingEnabled = enableLogging; this.currentTask = job; + // Create a new HandBrake instance + // Setup the HandBrake Instance + instance = new HandBrakeInstance(); + instance.Initialize(1); + instance.EncodeCompleted += this.InstanceEncodeCompleted; + instance.EncodeProgress += this.InstanceEncodeProgress; + try { // Sanity Checking and Setup @@ -111,9 +122,6 @@ namespace HandBrake.ApplicationServices.Services this.IsEncoding = true; - // Get an EncodeJob object for the Interop Library - EncodeJob encodeJob = InteropModelCreator.GetEncodeJob(job); - // Enable logging if required. if (enableLogging) { @@ -131,34 +139,14 @@ namespace HandBrake.ApplicationServices.Services // Verify the Destination Path Exists, and if not, create it. this.VerifyEncodeDestinationPath(job); - // Start the Encode - this.instance.StartEncode(encodeJob); - - // Set the Process Priority - switch (this.userSettingService.GetUserSetting(ASUserSettingConstants.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; - } + // We have to scan the source again but only the title so the HandBrake instance is initialised correctly. + // Since the UI sends the crop params down, we don't have to do all the previews. + instance.StartScan(job.Task.Source, 1, job.Task.Title); - // Fire the Encode Started Event - this.InvokeEncodeStarted(EventArgs.Empty); + instance.ScanCompleted += delegate + { + ScanCompleted(job, instance); + }; } catch (Exception exc) { @@ -166,6 +154,28 @@ namespace HandBrake.ApplicationServices.Services } } + /// + /// Pause the currently running encode. + /// + public void Pause() + { + if (this.instance != null) + { + this.instance.PauseEncode(); + } + } + + /// + /// Resume the currently running encode. + /// + public void Resume() + { + if (this.instance != null) + { + this.instance.ResumeEncode(); + } + } + /// /// Kill the CLI process /// @@ -190,6 +200,50 @@ namespace HandBrake.ApplicationServices.Services // Nothing to do for this implementation. } + /// + /// The scan completed. + /// + /// + /// The job. + /// + /// + /// The instance. + /// + private void ScanCompleted(QueueTask job, IHandBrakeInstance instance) + { + // Get an EncodeJob object for the Interop Library + EncodeJob encodeJob = InteropModelCreator.GetEncodeJob(job); + + // Start the Encode + instance.StartEncode(encodeJob); + + // Fire the Encode Started Event + this.InvokeEncodeStarted(EventArgs.Empty); + + // Set the Process Priority + switch (this.userSettingService.GetUserSetting(ASUserSettingConstants.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; + } + } + #region HandBrakeInstance Event Handlers. /// /// Log a message diff --git a/win/CS/HandBrake.ApplicationServices/Services/LibScan.cs b/win/CS/HandBrake.ApplicationServices/Services/LibScan.cs index 157380b8c..a6a634b53 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/LibScan.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/LibScan.cs @@ -13,7 +13,6 @@ namespace HandBrake.ApplicationServices.Services using System.Collections.Generic; using System.IO; using System.Text; - using System.Threading; using HandBrake.ApplicationServices.EventArgs; using HandBrake.ApplicationServices.Model.Encoding; diff --git a/win/CS/HandBrake.ApplicationServices/Services/ServerService.cs b/win/CS/HandBrake.ApplicationServices/Services/ServerService.cs index 4e0039c55..ab0acd596 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/ServerService.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/ServerService.cs @@ -16,8 +16,6 @@ namespace HandBrake.ApplicationServices.Services using HandBrake.ApplicationServices.Model; using HandBrake.ApplicationServices.Services.Interfaces; - using HandBrake.Interop; - using HandBrake.Interop.Interfaces; using EncodeCompletedEventArgs = HandBrake.ApplicationServices.EventArgs.EncodeCompletedEventArgs; using EncodeProgressEventArgs = HandBrake.ApplicationServices.EventArgs.EncodeProgressEventArgs; @@ -104,8 +102,7 @@ namespace HandBrake.ApplicationServices.Services Console.WriteLine("Service Started. Waiting for Clients..."); // Setup the services we are going to use. - IHandBrakeInstance instance = new HandBrakeInstance(); - encodeService = new LibEncode(new UserSettingService(), instance); // TODO this needs wired up with castle + encodeService = new LibEncode(new UserSettingService()); // TODO this needs wired up with castle shutdownFlag = new ManualResetEvent(false); shutdownFlag.WaitOne(); diff --git a/win/CS/HandBrake.ApplicationServices/Utilities/InteropModelCreator.cs b/win/CS/HandBrake.ApplicationServices/Utilities/InteropModelCreator.cs index b6a50485f..81b4a63c1 100644 --- a/win/CS/HandBrake.ApplicationServices/Utilities/InteropModelCreator.cs +++ b/win/CS/HandBrake.ApplicationServices/Utilities/InteropModelCreator.cs @@ -17,6 +17,7 @@ namespace HandBrake.ApplicationServices.Utilities using HandBrake.ApplicationServices.Model.Encoding; using HandBrake.Interop.Model; using HandBrake.Interop.Model.Encoding; + using HandBrake.Interop.Model.Encoding.x264; /// /// A Utility Class to Convert a @@ -45,12 +46,10 @@ namespace HandBrake.ApplicationServices.Utilities // Which will be converted to this EncodeJob Model. EncodeJob job = new EncodeJob(); - EncodingProfile profile = new EncodingProfile(); job.EncodingProfile = profile; - profile.Anamorphic = work.Anamorphic; - + // Audio Settings profile.AudioEncodings = new List(); job.ChosenAudioTracks = new List(); foreach (AudioTrack track in work.AudioTracks) @@ -63,7 +62,7 @@ namespace HandBrake.ApplicationServices.Utilities Encoder = Converters.GetCliAudioEncoder(track.Encoder), InputNumber = track.Track.HasValue ? track.Track.Value : 0, Mixdown = Converters.GetCliMixDown(track.MixDown), - SampleRateRaw = GetSampleRateRaw(track.SampleRate), + SampleRateRaw = GetSampleRateRaw(track.SampleRate), }; profile.AudioEncodings.Add(newTrack); @@ -72,6 +71,60 @@ namespace HandBrake.ApplicationServices.Utilities job.ChosenAudioTracks.Add(track.Track.Value); } } + + // Title Settings + job.OutputPath = work.Destination; + job.SourcePath = work.Source; + job.Title = work.Title; + // job.SourceType = work.Type; + switch (work.PointToPointMode) + { + case PointToPointMode.Chapters: + job.RangeType = VideoRangeType.Chapters; + break; + case PointToPointMode.Seconds: + job.RangeType = VideoRangeType.Seconds; + break; + case PointToPointMode.Frames: + job.RangeType = VideoRangeType.Frames; + break; + } + + if (work.PointToPointMode == PointToPointMode.Seconds) + { + job.SecondsEnd = work.EndPoint; + job.SecondsStart = work.StartPoint; + } + if (work.PointToPointMode == PointToPointMode.Chapters) + { + job.ChapterStart = work.StartPoint; + job.ChapterEnd = work.EndPoint; + } + if (work.PointToPointMode == PointToPointMode.Frames) + { + job.FramesEnd = work.EndPoint; + job.FramesStart = work.StartPoint; + } + + job.Angle = work.Angle; + job.EncodingProfile = profile; + + // Output Settings + profile.IPod5GSupport = work.IPod5GSupport; + profile.Optimize = work.OptimizeMP4; + switch (work.OutputFormat) + { + case OutputFormat.Mp4: + case OutputFormat.M4V: + profile.OutputFormat = Container.Mp4; + break; + case OutputFormat.Mkv: + profile.OutputFormat = Container.Mkv; + break; + } + + // Picture Settings + profile.Anamorphic = work.Anamorphic; profile.Cropping = new Cropping { Top = work.Cropping.Top, @@ -79,101 +132,63 @@ namespace HandBrake.ApplicationServices.Utilities Left = work.Cropping.Left, Right = work.Cropping.Right }; - profile.CroppingType = CroppingType.Custom; // TODO deal with this better + profile.DisplayWidth = work.DisplayWidth.HasValue + ? int.Parse(Math.Round(work.DisplayWidth.Value, 0).ToString()) + : 0; + profile.PixelAspectX = work.PixelAspectX; + profile.PixelAspectY = work.PixelAspectY; + profile.Height = work.Height.HasValue ? work.Height.Value : 0; + profile.KeepDisplayAspect = work.KeepDisplayAspect; + profile.MaxHeight = work.MaxHeight.HasValue ? work.MaxHeight.Value : 0; + profile.MaxWidth = work.MaxWidth.HasValue ? work.MaxWidth.Value : 0; + profile.Modulus = work.Modulus.HasValue ? work.Modulus.Value : 16; + profile.UseDisplayWidth = true; + profile.Width = work.Width.HasValue ? work.Width.Value : 0; + + // Filter Settings profile.CustomDecomb = work.CustomDecomb; profile.CustomDeinterlace = work.CustomDeinterlace; profile.CustomDenoise = work.CustomDenoise; profile.CustomDetelecine = work.CustomDetelecine; - profile.Deblock = work.Deblock; + if (work.Deblock > 4) + profile.Deblock = work.Deblock; profile.Decomb = work.Decomb; profile.Deinterlace = work.Deinterlace; profile.Denoise = work.Denoise; profile.Detelecine = work.Detelecine; - profile.DisplayWidth = work.DisplayWidth.HasValue - ? int.Parse(Math.Round(work.DisplayWidth.Value, 0).ToString()) - : 0; - profile.Framerate = work.Framerate.HasValue ? work.Framerate.Value : 0; profile.Grayscale = work.Grayscale; - profile.Height = work.Height.HasValue ? work.Height.Value : 0; - profile.IPod5GSupport = work.IPod5GSupport; - profile.IncludeChapterMarkers = work.IncludeChapterMarkers; - profile.KeepDisplayAspect = work.KeepDisplayAspect; - profile.MaxHeight = work.MaxHeight.HasValue ? work.MaxHeight.Value : 0; - profile.MaxWidth = work.MaxWidth.HasValue ? work.MaxWidth.Value : 0; - profile.Modulus = work.Modulus.HasValue ? work.Modulus.Value : 16; - profile.Optimize = work.OptimizeMP4; - switch (work.OutputFormat) - { - case OutputFormat.Mp4: - case OutputFormat.M4V: - profile.OutputFormat = Container.Mp4; - break; - case OutputFormat.Mkv: - profile.OutputFormat = Container.Mkv; - break; - } - profile.ConstantFramerate = work.FramerateMode == FramerateMode.CFR; - profile.PixelAspectX = work.PixelAspectX; - profile.PixelAspectY = work.PixelAspectY; - switch (work.OutputFormat) - { - case OutputFormat.Mp4: - profile.PreferredExtension = OutputExtension.Mp4; - break; - case OutputFormat.M4V: - profile.PreferredExtension = OutputExtension.M4v; - break; - } + // Video Settings + profile.Framerate = work.Framerate.HasValue ? work.Framerate.Value : 0; + profile.ConstantFramerate = work.FramerateMode == FramerateMode.CFR; profile.Quality = work.Quality.HasValue ? work.Quality.Value : 0; - profile.UseDisplayWidth = true; profile.VideoBitrate = work.VideoBitrate.HasValue ? work.VideoBitrate.Value : 0; profile.VideoEncodeRateType = work.VideoEncodeRateType; profile.VideoEncoder = Converters.GetVideoEncoder(work.VideoEncoder); - profile.Width = work.Width.HasValue ? work.Width.Value : 0; - profile.X264Options = work.AdvancedEncoderOptions; - if (work.PointToPointMode == PointToPointMode.Chapters) + profile.H264Level = work.H264Level; + profile.X264Profile = work.H264Profile.ToString().ToLower().Replace(" ", string.Empty); // TODO change these away from strings. + profile.X264Preset = work.X264Preset.ToString().ToLower().Replace(" ", string.Empty); + profile.X264Tunes = new List(); + + if (work.X264Tune != x264Tune.None) { - job.ChapterStart = work.StartPoint; - job.ChapterEnd = work.EndPoint; + profile.X264Tunes.Add(work.X264Tune.ToString().ToLower().Replace(" ", string.Empty)); } - job.Angle = work.Angle; - job.EncodingProfile = profile; - if (work.PointToPointMode == PointToPointMode.Frames) + if (work.FastDecode) { - job.FramesEnd = work.EndPoint; - job.FramesStart = work.StartPoint; + profile.X264Tunes.Add("fastdecode"); } + // Chapter Markers + profile.IncludeChapterMarkers = work.IncludeChapterMarkers; job.CustomChapterNames = work.ChapterNames.Select(item => item.ChapterName).ToList(); job.UseDefaultChapterNames = work.IncludeChapterMarkers; - job.OutputPath = work.Destination; - switch (work.PointToPointMode) - { - case PointToPointMode.Chapters: - job.RangeType = VideoRangeType.Chapters; - break; - case PointToPointMode.Seconds: - job.RangeType = VideoRangeType.Seconds; - break; - case PointToPointMode.Frames: - job.RangeType = VideoRangeType.Frames; - break; - } - - if (work.PointToPointMode == PointToPointMode.Seconds) - { - job.SecondsEnd = work.EndPoint; - job.SecondsStart = work.StartPoint; - } - - job.SourcePath = work.Source; - // job.SourceType = work.Type; - job.Title = work.Title; + // Advanced Settings + profile.X264Options = work.AdvancedEncoderOptions; // Subtitles job.Subtitles = new Subtitles { SourceSubtitles = new List(), SrtSubtitles = new List() }; -- cgit v1.2.3