summaryrefslogtreecommitdiffstats
path: root/win/CS/HandBrake.ApplicationServices/Services
diff options
context:
space:
mode:
authorsr55 <[email protected]>2013-01-26 16:05:48 +0000
committersr55 <[email protected]>2013-01-26 16:05:48 +0000
commit5aa8001465c0e94ac2470969613042bff221c6d4 (patch)
tree9095d88486ef17e2096b9a1338e218db93a0b404 /win/CS/HandBrake.ApplicationServices/Services
parentd1bb73fbe199809f37ac17da3b104f9e2c97880f (diff)
WinGui: Numerous bug fixes to the services library.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@5205 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'win/CS/HandBrake.ApplicationServices/Services')
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs91
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/Encode.cs187
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs4
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs19
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs13
5 files changed, 155 insertions, 159 deletions
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs b/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs
index 8ef67b28d..67cad52e5 100644
--- a/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs
+++ b/win/CS/HandBrake.ApplicationServices/Services/Base/EncodeBase.cs
@@ -10,8 +10,10 @@
namespace HandBrake.ApplicationServices.Services.Base
{
using System;
+ using System.Globalization;
using System.IO;
using System.Text;
+ using System.Text.RegularExpressions;
using HandBrake.ApplicationServices.EventArgs;
using HandBrake.ApplicationServices.Exceptions;
@@ -192,10 +194,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 +248,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 +352,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 +390,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/LibEncode.cs b/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs
index 64d604a34..f194700ed 100644
--- a/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs
+++ b/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs
@@ -169,19 +169,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 +180,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)
{