diff options
author | sr55 <[email protected]> | 2013-02-02 15:12:19 +0000 |
---|---|---|
committer | sr55 <[email protected]> | 2013-02-02 15:12:19 +0000 |
commit | a7dfaa518ce3aaf73a64ecc3c61a88c9427aef81 (patch) | |
tree | 8efccea1be99fb4aca2fe1ad028c395095500675 /win/CS/HandBrake.ApplicationServices/Services | |
parent | bc3b56381c6ac214b7736a00972c9d0902902453 (diff) |
Merging trunk to cl branch.
git-svn-id: svn://svn.handbrake.fr/HandBrake/branches/opencl@5234 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'win/CS/HandBrake.ApplicationServices/Services')
7 files changed, 224 insertions, 175 deletions
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs b/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs index 8ef67b28d..866edb794 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs @@ -10,8 +10,12 @@ namespace HandBrake.ApplicationServices.Services.Base
{
using System;
+ using System.Globalization;
using System.IO;
using System.Text;
+ using System.Text.RegularExpressions;
+
+ using Caliburn.Micro;
using HandBrake.ApplicationServices.EventArgs;
using HandBrake.ApplicationServices.Exceptions;
@@ -148,11 +152,15 @@ namespace HandBrake.ApplicationServices.Services.Base /// </param>
public void InvokeEncodeStatusChanged(EncodeProgressEventArgs e)
{
- EncodeProgessStatus handler = this.EncodeStatusChanged;
- if (handler != null)
- {
- handler(this, e);
- }
+ Execute.OnUIThread(
+ () =>
+ {
+ EncodeProgessStatus handler = this.EncodeStatusChanged;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ });
}
/// <summary>
@@ -163,11 +171,15 @@ namespace HandBrake.ApplicationServices.Services.Base /// </param>
public void InvokeEncodeCompleted(EncodeCompletedEventArgs e)
{
- EncodeCompletedStatus handler = this.EncodeCompleted;
- if (handler != null)
- {
- handler(this, e);
- }
+ Execute.OnUIThread(
+ () =>
+ {
+ EncodeCompletedStatus handler = this.EncodeCompleted;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ });
}
/// <summary>
@@ -178,11 +190,14 @@ namespace HandBrake.ApplicationServices.Services.Base /// </param>
public void InvokeEncodeStarted(EventArgs e)
{
- EventHandler handler = this.EncodeStarted;
- if (handler != null)
- {
- handler(this, e);
- }
+ Execute.OnUIThread(() =>
+ {
+ EventHandler handler = this.EncodeStarted;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ });
}
#endregion
@@ -192,10 +207,7 @@ namespace HandBrake.ApplicationServices.Services.Base /// <summary>
/// A Stop Method to be implemeneted.
/// </summary>
- /// <param name="exc">
- /// The Exception that occured that required a STOP action.
- /// </param>
- public virtual void Stop(Exception exc)
+ public virtual void Stop()
{
// Do Nothing
}
@@ -249,6 +261,73 @@ namespace HandBrake.ApplicationServices.Services.Base }
}
+
+ /// <summary>
+ /// Pase the CLI status output (from standard output)
+ /// </summary>
+ /// <param name="encodeStatus">
+ /// The encode Status.
+ /// </param>
+ /// <param name="startTime">
+ /// The start Time.
+ /// </param>
+ /// <returns>
+ /// The <see cref="EncodeProgressEventArgs"/>.
+ /// </returns>
+ public EncodeProgressEventArgs ReadEncodeStatus(string encodeStatus, DateTime startTime)
+ {
+ try
+ {
+ Match m = Regex.Match(
+ encodeStatus,
+ @"^Encoding: task ([0-9]*) of ([0-9]*), ([0-9]*\.[0-9]*) %( \(([0-9]*\.[0-9]*) fps, avg ([0-9]*\.[0-9]*) fps, ETA ([0-9]{2})h([0-9]{2})m([0-9]{2})s\))?");
+
+ if (m.Success)
+ {
+ int currentTask = int.Parse(m.Groups[1].Value);
+ int totalTasks = int.Parse(m.Groups[2].Value);
+ float percent = float.Parse(m.Groups[3].Value, CultureInfo.InvariantCulture);
+ float currentFps = m.Groups[5].Value == string.Empty
+ ? 0.0F
+ : float.Parse(m.Groups[5].Value, CultureInfo.InvariantCulture);
+ float avgFps = m.Groups[6].Value == string.Empty
+ ? 0.0F
+ : float.Parse(m.Groups[6].Value, CultureInfo.InvariantCulture);
+ string remaining = string.Empty;
+ if (m.Groups[7].Value != string.Empty)
+ {
+ remaining = m.Groups[7].Value + ":" + m.Groups[8].Value + ":" + m.Groups[9].Value;
+ }
+ if (string.IsNullOrEmpty(remaining))
+ {
+ remaining = "Calculating ...";
+ }
+
+ EncodeProgressEventArgs eventArgs = new EncodeProgressEventArgs
+ {
+ AverageFrameRate = avgFps,
+ CurrentFrameRate = currentFps,
+ EstimatedTimeLeft =
+ Converters.EncodeToTimespan(
+ remaining),
+ PercentComplete = percent,
+ Task = currentTask,
+ TaskCount = totalTasks,
+ ElapsedTime =
+ DateTime.Now - startTime,
+ };
+
+ return eventArgs;
+ }
+
+ return null;
+ }
+ catch (Exception exc)
+ {
+ return null;
+ }
+ }
+
/// <summary>
/// Setup the logging.
/// </summary>
@@ -286,8 +365,8 @@ namespace HandBrake.ApplicationServices.Services.Base this.fileWriter = new StreamWriter(logFile) { AutoFlush = true };
this.fileWriter.WriteLine(header);
- this.fileWriter.WriteLine(String.Format("CLI Query: {0}", query));
- this.fileWriter.WriteLine(String.Format("User Query: {0}", encodeQueueTask.CustomQuery));
+ this.fileWriter.WriteLine(string.Format("CLI Query: {0}", query));
+ this.fileWriter.WriteLine(string.Format("User Query: {0}", encodeQueueTask.CustomQuery));
this.fileWriter.WriteLine();
}
catch (Exception)
@@ -324,22 +403,9 @@ namespace HandBrake.ApplicationServices.Services.Base if (this.fileWriter != null && this.fileWriter.BaseStream.CanWrite)
{
this.fileWriter.WriteLine(message);
-
- // If the logging grows past 100MB, kill the encode and stop.
- if (this.fileWriter.BaseStream.Length > 100000000)
- {
- this.Stop(
- new GeneralApplicationException(
- "The encode has been stopped. The log file has grown to over 100MB which indicates a serious problem has occured with the encode.",
- "Please check the encode log for an indication of what the problem is.", null));
- }
}
}
}
- catch (GeneralApplicationException)
- {
- throw;
- }
catch (Exception exc)
{
// Do Nothing.
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Encode.cs b/win/CS/HandBrake.ApplicationServices/Services/Encode.cs index c136c18ee..577067050 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/Encode.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/Encode.cs @@ -11,18 +11,18 @@ namespace HandBrake.ApplicationServices.Services {
using System;
using System.Diagnostics;
+ using System.Globalization;
using System.IO;
- using System.Threading;
using System.Windows.Forms;
+ using Caliburn.Micro;
+
using HandBrake.ApplicationServices.EventArgs;
using HandBrake.ApplicationServices.Model;
using HandBrake.ApplicationServices.Services.Base;
using HandBrake.ApplicationServices.Services.Interfaces;
using HandBrake.ApplicationServices.Utilities;
- using Parser = HandBrake.ApplicationServices.Parsing.Parser;
-
/// <summary>
/// Class which handles the CLI
/// </summary>
@@ -36,11 +36,6 @@ namespace HandBrake.ApplicationServices.Services private readonly IUserSettingService userSettingService;
/// <summary>
- /// Gets The Process Handle
- /// </summary>
- private IntPtr processHandle;
-
- /// <summary>
/// Gets the Process ID
/// </summary>
private int processId;
@@ -55,6 +50,11 @@ namespace HandBrake.ApplicationServices.Services /// </summary>
private QueueTask currentTask;
+ /// <summary>
+ /// The init shutdown.
+ /// </summary>
+ private bool initShutdown;
+
#endregion
/// <summary>
@@ -66,8 +66,7 @@ namespace HandBrake.ApplicationServices.Services public Encode(IUserSettingService userSettingService)
: base(userSettingService)
{
- this.userSettingService = userSettingService;
- this.EncodeStarted += this.EncodeEncodeStarted;
+ this.userSettingService = userSettingService;
}
#region Properties
@@ -83,6 +82,7 @@ namespace HandBrake.ApplicationServices.Services /// <summary>
/// Execute a HandBrakeCLI process.
+ /// This should only be called from the UI thread.
/// </summary>
/// <param name="encodeQueueTask">
/// The encodeQueueTask.
@@ -94,8 +94,6 @@ namespace HandBrake.ApplicationServices.Services {
try
{
- this.currentTask = encodeQueueTask;
-
if (this.IsEncoding)
{
throw new Exception("HandBrake is already encodeing.");
@@ -103,6 +101,8 @@ namespace HandBrake.ApplicationServices.Services this.IsEncoding = true;
+ this.currentTask = encodeQueueTask;
+
if (enableLogging)
{
try
@@ -160,8 +160,10 @@ namespace HandBrake.ApplicationServices.Services this.HbProcess.BeginErrorReadLine();
}
+ this.HbProcess.OutputDataReceived += HbProcess_OutputDataReceived;
+ this.HbProcess.BeginOutputReadLine();
+
this.processId = this.HbProcess.Id;
- this.processHandle = this.HbProcess.Handle;
// Set the process Priority
if (this.processId != -1)
@@ -207,21 +209,9 @@ namespace HandBrake.ApplicationServices.Services }
/// <summary>
- /// Stop the Encode
- /// </summary>
- public void Stop()
- {
- this.Stop(null);
- }
-
- /// <summary>
/// Kill the CLI process
/// </summary>
- /// <param name="exc">
- /// The Exception that has occured.
- /// This will get bubbled up through the EncodeCompletedEventArgs
- /// </param>
- public override void Stop(Exception exc)
+ public override void Stop()
{
try
{
@@ -234,11 +224,6 @@ namespace HandBrake.ApplicationServices.Services {
// No need to report anything to the user. If it fails, it's probably already stopped.
}
-
- this.InvokeEncodeCompleted(
- exc == null
- ? new EncodeCompletedEventArgs(true, null, string.Empty)
- : new EncodeCompletedEventArgs(false, exc, "An Unknown Error has occured when trying to Stop this encode."));
}
/// <summary>
@@ -264,25 +249,12 @@ namespace HandBrake.ApplicationServices.Services /// </param>
private void HbProcessExited(object sender, EventArgs e)
{
- this.IsEncoding = false;
- if (this.WindowsSeven.IsWindowsSeven)
- {
- this.WindowsSeven.SetTaskBarProgressToNoProgress();
- }
-
- if (this.userSettingService.GetUserSetting<bool>(ASUserSettingConstants.PreventSleep))
- {
- Win32.AllowSleep();
- }
+ HbProcess.WaitForExit();
try
{
- // This is just a quick hack to ensure that we are done processing the logging data.
- // Logging data comes in after the exit event has processed sometimes. We should really impliment ISyncronizingInvoke
- // and set the SyncObject on the process. I think this may resolve this properly.
- // For now, just wait 2.5 seconds to let any trailing log messages come in and be processed.
- Thread.Sleep(2500);
this.HbProcess.CancelErrorRead();
+ this.HbProcess.CancelOutputRead();
this.ShutdownFileWriter();
}
catch (Exception exc)
@@ -290,8 +262,22 @@ namespace HandBrake.ApplicationServices.Services // This exception doesn't warrent user interaction, but it should be logged (TODO)
}
- this.currentTask.Status = QueueItemStatus.Completed;
- this.InvokeEncodeCompleted(new EncodeCompletedEventArgs(true, null, string.Empty));
+ Execute.OnUIThread(() =>
+ {
+ if (this.WindowsSeven.IsWindowsSeven)
+ {
+ this.WindowsSeven.SetTaskBarProgressToNoProgress();
+ }
+
+ if (this.userSettingService.GetUserSetting<bool>(ASUserSettingConstants.PreventSleep))
+ {
+ Win32.AllowSleep();
+ }
+
+ this.currentTask.Status = QueueItemStatus.Completed;
+ this.IsEncoding = false;
+ this.InvokeEncodeCompleted(new EncodeCompletedEventArgs(true, null, string.Empty));
+ });
}
/// <summary>
@@ -303,88 +289,69 @@ namespace HandBrake.ApplicationServices.Services /// <param name="e">
/// DataReceived EventArgs
/// </param>
+ /// <remarks>
+ /// Worker Thread.
+ /// </remarks>
private void HbProcErrorDataReceived(object sender, DataReceivedEventArgs e)
{
if (!String.IsNullOrEmpty(e.Data))
{
+ if (initShutdown && this.LogBuffer.Length < 25000000)
+ {
+ initShutdown = false; // Reset this flag.
+ }
+
+ if (this.LogBuffer.Length > 25000000 && !initShutdown) // Approx 23.8MB and make sure it's only printed once
+ {
+ this.ProcessLogMessage("ERROR: Initiating automatic shutdown of encode process. The size of the log file inidcates that there is an error! ");
+ initShutdown = true;
+ this.Stop();
+ }
+
this.ProcessLogMessage(e.Data);
}
}
/// <summary>
- /// Encode Started
+ /// The hb process output data received.
/// </summary>
/// <param name="sender">
/// The sender.
/// </param>
/// <param name="e">
- /// The EventArgs.
+ /// The e.
/// </param>
- private void EncodeEncodeStarted(object sender, EventArgs e)
+ private void HbProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
- Thread monitor = new Thread(this.EncodeMonitor);
- monitor.Start();
- }
-
- /// <summary>
- /// Monitor the QueueTask
- /// </summary>
- private void EncodeMonitor()
- {
- try
+ if (!String.IsNullOrEmpty(e.Data) && this.IsEncoding)
{
- Parser encode = new Parser(this.HbProcess.StandardOutput.BaseStream);
- encode.OnEncodeProgress += this.EncodeOnEncodeProgress;
- while (!encode.EndOfStream)
+ EncodeProgressEventArgs eventArgs = this.ReadEncodeStatus(e.Data, this.startTime);
+ if (eventArgs != null)
{
- encode.ReadEncodeStatus();
+ Execute.OnUIThread(
+ () =>
+ {
+ if (!this.IsEncoding)
+ {
+ // We can get events out of order since the CLI progress is monitored on a background thread.
+ // So make sure we don't send a status update after an encode complete event.
+ return;
+ }
+
+ this.InvokeEncodeStatusChanged(eventArgs);
+
+ if (this.WindowsSeven.IsWindowsSeven)
+ {
+ int percent;
+ int.TryParse(
+ Math.Round(eventArgs.PercentComplete).ToString(CultureInfo.InvariantCulture),
+ out percent);
+
+ this.WindowsSeven.SetTaskBarProgress(percent);
+ }
+ });
}
}
- catch (Exception)
- {
- this.EncodeOnEncodeProgress(null, 0, 0, 0, 0, 0, "Unknown, status not available..");
- }
- }
-
- /// <summary>
- /// Displays the Encode status in the GUI
- /// </summary>
- /// <param name="sender">The sender</param>
- /// <param name="currentTask">The current task</param>
- /// <param name="taskCount">Number of tasks</param>
- /// <param name="percentComplete">Percent complete</param>
- /// <param name="currentFps">Current encode speed in fps</param>
- /// <param name="avg">Avg encode speed</param>
- /// <param name="timeRemaining">Time Left</param>
- private void EncodeOnEncodeProgress(object sender, int currentTask, int taskCount, float percentComplete, float currentFps, float avg, string timeRemaining)
- {
- if (!this.IsEncoding)
- {
- // We can get events out of order since the CLI progress is monitored on a background thread.
- // So make sure we don't send a status update after an encode complete event.
- return;
- }
-
- EncodeProgressEventArgs eventArgs = new EncodeProgressEventArgs
- {
- AverageFrameRate = avg,
- CurrentFrameRate = currentFps,
- EstimatedTimeLeft = Converters.EncodeToTimespan(timeRemaining),
- PercentComplete = percentComplete,
- Task = currentTask,
- TaskCount = taskCount,
- ElapsedTime = DateTime.Now - this.startTime,
- };
-
- this.InvokeEncodeStatusChanged(eventArgs);
-
- if (this.WindowsSeven.IsWindowsSeven)
- {
- int percent;
- int.TryParse(Math.Round(percentComplete).ToString(), out percent);
-
- this.WindowsSeven.SetTaskBarProgress(percent);
- }
}
#endregion
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs index 0a952e516..b4c8872c0 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs @@ -10,7 +10,7 @@ namespace HandBrake.ApplicationServices.Services.Interfaces
{
using System;
- using System.Collections.ObjectModel;
+ using System.ComponentModel;
using HandBrake.ApplicationServices.Model;
@@ -70,7 +70,7 @@ namespace HandBrake.ApplicationServices.Services.Interfaces /// <summary>
/// Gets The current queue.
/// </summary>
- ObservableCollection<QueueTask> Queue { get; }
+ BindingList<QueueTask> Queue { get; }
#endregion
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IUserSettingService.cs b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IUserSettingService.cs index d7bba9550..bf6cb9c91 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IUserSettingService.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IUserSettingService.cs @@ -9,12 +9,30 @@ namespace HandBrake.ApplicationServices.Services.Interfaces
{
+ using HandBrake.ApplicationServices.EventArgs;
+
+ /// <summary>
+ /// The setting event handler.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ public delegate void SettingEventHandler(object sender, SettingChangedEventArgs e);
+
/// <summary>
/// The User Setting Service Interace.
/// </summary>
public interface IUserSettingService
{
/// <summary>
+ /// The setting changed.
+ /// </summary>
+ event SettingEventHandler SettingChanged;
+
+ /// <summary>
/// Set the specified user setting.
/// </summary>
/// <param name="name">
diff --git a/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs b/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs index 64d604a34..320b96f1b 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs @@ -12,7 +12,6 @@ namespace HandBrake.ApplicationServices.Services using System;
using System.Diagnostics;
- using HandBrake.ApplicationServices.Exceptions;
using HandBrake.ApplicationServices.Model;
using HandBrake.ApplicationServices.Services.Base;
using HandBrake.ApplicationServices.Services.Interfaces;
@@ -169,19 +168,7 @@ namespace HandBrake.ApplicationServices.Services /// <summary>
/// Kill the CLI process
/// </summary>
- public void Stop()
- {
- this.Stop(null);
- }
-
- /// <summary>
- /// Kill the CLI process
- /// </summary>
- /// <param name="exc">
- /// The Exception that has occured.
- /// This will get bubbled up through the EncodeCompletedEventArgs
- /// </param>
- public override void Stop(Exception exc)
+ public override void Stop()
{
try
{
@@ -192,11 +179,6 @@ namespace HandBrake.ApplicationServices.Services {
// Do Nothing.
}
-
- this.InvokeEncodeCompleted(
- exc == null
- ? new EncodeCompletedEventArgs(true, null, string.Empty)
- : new EncodeCompletedEventArgs(false, exc, "An Error has occured."));
}
/// <summary>
diff --git a/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs b/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs index 7aefd285f..172fe7291 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs @@ -11,7 +11,7 @@ namespace HandBrake.ApplicationServices.Services {
using System;
using System.Collections.Generic;
- using System.Collections.ObjectModel;
+ using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -41,7 +41,7 @@ namespace HandBrake.ApplicationServices.Services /// <summary>
/// The Queue of Job objects
/// </summary>
- private readonly ObservableCollection<QueueTask> queue = new ObservableCollection<QueueTask>();
+ private readonly BindingList<QueueTask> queue = new BindingList<QueueTask>();
/// <summary>
/// The User Setting Service
@@ -152,7 +152,7 @@ namespace HandBrake.ApplicationServices.Services /// <summary>
/// Gets The current queue.
/// </summary>
- public ObservableCollection<QueueTask> Queue
+ public BindingList<QueueTask> Queue
{
get
{
@@ -595,13 +595,6 @@ namespace HandBrake.ApplicationServices.Services /// </summary>
private void ProcessNextJob()
{
- if (this.EncodeService.IsEncoding || !this.IsProcessing)
- {
- // We don't want to try start a second encode, so just return out. The event will trigger the next encode automatically.
- // Also, we don't want to start a new encode if we are paused.
- return;
- }
-
QueueTask job = this.GetNextJobForProcessing();
if (job != null)
{
diff --git a/win/CS/HandBrake.ApplicationServices/Services/UserSettingService.cs b/win/CS/HandBrake.ApplicationServices/Services/UserSettingService.cs index ab77ce800..db7389637 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/UserSettingService.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/UserSettingService.cs @@ -16,6 +16,7 @@ namespace HandBrake.ApplicationServices.Services using System.Xml.Serialization;
using HandBrake.ApplicationServices.Collections;
+ using HandBrake.ApplicationServices.EventArgs;
using HandBrake.ApplicationServices.Exceptions;
using HandBrake.ApplicationServices.Services.Interfaces;
@@ -48,6 +49,11 @@ namespace HandBrake.ApplicationServices.Services }
/// <summary>
+ /// The setting changed.
+ /// </summary>
+ public event SettingEventHandler SettingChanged;
+
+ /// <summary>
/// Set the specified user setting.
/// </summary>
/// <param name="name">
@@ -60,6 +66,8 @@ namespace HandBrake.ApplicationServices.Services {
this.userSettings[name] = value;
this.Save();
+
+ this.OnSettingChanged(new SettingChangedEventArgs {Key = name, Value = value});
}
/// <summary>
@@ -99,6 +107,21 @@ namespace HandBrake.ApplicationServices.Services }
/// <summary>
+ /// The on setting changed.
+ /// </summary>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ protected virtual void OnSettingChanged(SettingChangedEventArgs e)
+ {
+ SettingEventHandler handler = this.SettingChanged;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ }
+
+ /// <summary>
/// Save the User Settings
/// </summary>
private void Save()
|