+/* Title.cs $\r
+ \r
+ This file is part of the HandBrake source code.\r
+ Homepage: <http://handbrake.fr>.\r
+ It may be used under the terms of the GNU General Public License. */\r
+\r
using System;\r
using System.Collections.Generic;\r
using System.Drawing;\r
+using System.Globalization;\r
using System.IO;\r
-using System.Windows.Forms;\r
using System.Text.RegularExpressions;\r
\r
namespace Handbrake.Parsing\r
/// </summary>\r
public class Title\r
{\r
- private List<Chapter> m_chapters;\r
+ private static readonly CultureInfo Culture = new CultureInfo("en-US", false);\r
+ private readonly List<AudioTrack> m_audioTracks;\r
+ private readonly List<Chapter> m_chapters;\r
+ private readonly List<Subtitle> m_subtitles;\r
+ private List<String> m_angles = new List<string>();\r
+ private float m_aspectRatio;\r
+ private int[] m_autoCrop;\r
+ private TimeSpan m_duration;\r
+ private Size m_resolution;\r
+ private int m_titleNumber;\r
+ private Size m_parVal;\r
+ \r
+ /// <summary>\r
+ /// The constructor for this object\r
+ /// </summary>\r
+ public Title()\r
+ {\r
+ m_audioTracks = new List<AudioTrack>();\r
+ m_chapters = new List<Chapter>();\r
+ m_subtitles = new List<Subtitle>();\r
+ }\r
+\r
/// <summary>\r
/// Collection of chapters in this Title\r
/// </summary>\r
public List<Chapter> Chapters\r
{\r
- get\r
- {\r
- return this.m_chapters;\r
- }\r
+ get { return m_chapters; }\r
}\r
\r
- private List<AudioTrack> m_audioTracks;\r
/// <summary>\r
/// Collection of audio tracks associated with this Title\r
/// </summary>\r
public List<AudioTrack> AudioTracks\r
{\r
- get\r
- {\r
- return this.m_audioTracks;\r
- }\r
+ get { return m_audioTracks; }\r
}\r
\r
- private List<Subtitle> m_subtitles;\r
/// <summary>\r
/// Collection of subtitles associated with this Title\r
/// </summary>\r
public List<Subtitle> Subtitles\r
{\r
- get\r
- {\r
- return this.m_subtitles;\r
- }\r
+ get { return m_subtitles; }\r
}\r
\r
- private int m_titleNumber;\r
/// <summary>\r
/// The track number of this Title\r
/// </summary>\r
public int TitleNumber\r
{\r
- get\r
- {\r
- return this.m_titleNumber;\r
- }\r
+ get { return m_titleNumber; }\r
}\r
\r
- private TimeSpan m_duration;\r
/// <summary>\r
/// The length in time of this Title\r
/// </summary>\r
public TimeSpan Duration\r
{\r
- get\r
- {\r
- return this.m_duration;\r
- }\r
+ get { return m_duration; }\r
}\r
\r
- private Size m_resolution;\r
/// <summary>\r
/// The resolution (width/height) of this Title\r
/// </summary>\r
public Size Resolution\r
{\r
- get\r
- {\r
- return this.m_resolution;\r
- }\r
+ get { return m_resolution; }\r
}\r
\r
- private float m_aspectRatio;\r
/// <summary>\r
/// The aspect ratio of this Title\r
/// </summary>\r
public float AspectRatio\r
{\r
- get\r
- {\r
- return this.m_aspectRatio;\r
- }\r
+ get { return m_aspectRatio; }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Par Value\r
+ /// </summary>\r
+ public Size ParVal\r
+ {\r
+ get { return m_parVal; }\r
}\r
\r
- private int[] m_autoCrop;\r
/// <summary>\r
/// The automatically detected crop region for this Title.\r
/// This is an int array with 4 items in it as so:\r
/// </summary>\r
public int[] AutoCropDimensions\r
{\r
- get\r
- {\r
- return this.m_autoCrop;\r
- }\r
+ get { return m_autoCrop; }\r
}\r
\r
/// <summary>\r
- /// The constructor for this object\r
+ /// Collection of Angles in this Title\r
/// </summary>\r
- public Title()\r
+ public List<string> Angles\r
{\r
- this.m_audioTracks = new List<AudioTrack>();\r
- this.m_chapters = new List<Chapter>();\r
- this.m_subtitles = new List<Subtitle>();\r
+ get { return m_angles; }\r
}\r
-\r
+ \r
/// <summary>\r
/// Override of the ToString method to provide an easy way to use this object in the UI\r
/// </summary>\r
/// <returns>A string representing this track in the format: {title #} (00:00:00)</returns>\r
public override string ToString()\r
{\r
- return string.Format("{0} ({1:00}:{2:00}:{3:00})", this.m_titleNumber, this.m_duration.Hours,\r
- this.m_duration.Minutes, this.m_duration.Seconds);\r
+ return string.Format("{0} ({1:00}:{2:00}:{3:00})", m_titleNumber, m_duration.Hours,\r
+ m_duration.Minutes, m_duration.Seconds);\r
}\r
\r
-\r
- /*\r
- * \r
- * There is some pretty extensive exception handling in here. A number of people have been seeing random problems.\r
- * It just helps pinpointing which line of code is causing the issue.\r
- * Can be cut down at a later date.\r
- * \r
- */\r
public static Title Parse(StringReader output)\r
{\r
- Title thisTitle = new Title();\r
- try\r
- {\r
- Match m = Regex.Match(output.ReadLine(), @"^\+ title ([0-9]*):");\r
- try\r
- {\r
- // Match track number for this title\r
- if (m.Success)\r
- {\r
- //MessageBox.Show(m.Groups[1].Value);\r
- thisTitle.m_titleNumber = int.Parse(m.Groups[1].Value.Trim().ToString()); \r
- //.Trim().ToString() Not sure why this is needed but some systems seem to get a rogue \r
- }\r
- }\r
- catch (Exception exc)\r
- {\r
- if (Properties.Settings.Default.GuiDebug == "Checked")\r
- {\r
- MessageBox.Show("Title.cs - Track Number " + exc.ToString());\r
- }\r
- }\r
+ var thisTitle = new Title();\r
\r
- output.ReadLine();\r
+ Match m = Regex.Match(output.ReadLine(), @"^\+ title ([0-9]*):");\r
+ // Match track number for this title\r
+ if (m.Success)\r
+ thisTitle.m_titleNumber = int.Parse(m.Groups[1].Value.Trim());\r
\r
- // Get duration for this title\r
- try\r
- {\r
- m = Regex.Match(output.ReadLine(), @"^ \+ duration: ([0-9]{2}:[0-9]{2}:[0-9]{2})");\r
- if (m.Success)\r
- {\r
- thisTitle.m_duration = TimeSpan.Parse(m.Groups[1].Value);\r
- }\r
- }\r
- catch (Exception exc)\r
- {\r
- if (Properties.Settings.Default.GuiDebug == "Checked")\r
- {\r
- MessageBox.Show("Title.cs - Duration " + exc.ToString());\r
- }\r
- }\r
+ output.ReadLine();\r
\r
- try\r
- {\r
- // Get resolution, aspect ratio and FPS for this title\r
- m = Regex.Match(output.ReadLine(), @"^ \+ size: ([0-9]*)x([0-9]*), aspect: ([0-9]*\.[0-9]*), ([0-9]*\.[0-9]*) fps");\r
- if (m.Success)\r
- {\r
- thisTitle.m_resolution = new Size(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value));\r
- thisTitle.m_aspectRatio = float.Parse(m.Groups[3].Value, Functions.CLI.Culture);\r
- }\r
- }\r
- catch (Exception exc)\r
+ if (!Properties.Settings.Default.noDvdNav)\r
+ {\r
+ // Get the Angles for the title.\r
+ m = Regex.Match(output.ReadLine(), @" \+ angle\(s\) ([0-9,])");\r
+ if (m.Success)\r
{\r
- if (Properties.Settings.Default.GuiDebug == "Checked")\r
- {\r
- MessageBox.Show("Title.cs - Resolution and Aspect " + exc.ToString());\r
- }\r
- }\r
+ String angleList = m.Value.Replace("+ angle(s) ", "").Trim();\r
\r
- try\r
- {\r
- // Get autocrop region for this title\r
- m = Regex.Match(output.ReadLine(), @"^ \+ autocrop: ([0-9]*)/([0-9]*)/([0-9]*)/([0-9]*)");\r
- if (m.Success)\r
+ if (angleList.Contains(","))\r
{\r
- thisTitle.m_autoCrop = new int[4] { int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value), int.Parse(m.Groups[3].Value), int.Parse(m.Groups[4].Value) };\r
- }\r
- }\r
- catch (Exception exc)\r
- {\r
- if (Properties.Settings.Default.GuiDebug == "Checked")\r
- {\r
- MessageBox.Show("Title.cs - Auto Crop " + exc.ToString());\r
+ string[] angles = angleList.Split(',');\r
+ foreach (string s in angles)\r
+ thisTitle.m_angles.Add(s);\r
}\r
+ else\r
+ thisTitle.m_angles.Add(m.Value.Replace("+ angle(s) ", "").Trim());\r
}\r
+ }\r
\r
+ // Get duration for this title\r
+ m = Regex.Match(output.ReadLine(), @"^ \+ duration: ([0-9]{2}:[0-9]{2}:[0-9]{2})");\r
+ if (m.Success)\r
+ thisTitle.m_duration = TimeSpan.Parse(m.Groups[1].Value);\r
\r
- try\r
- {\r
- thisTitle.m_chapters.AddRange(Chapter.ParseList(output));\r
- }\r
- catch (Exception exc)\r
- {\r
- if (Properties.Settings.Default.GuiDebug == "Checked")\r
- {\r
- MessageBox.Show("Title.cs - Chapters EXC " + exc.ToString());\r
- }\r
- }\r
+ // Get resolution, aspect ratio and FPS for this title\r
+ m = Regex.Match(output.ReadLine(),\r
+ @"^ \+ size: ([0-9]*)x([0-9]*), pixel aspect: ([0-9]*)/([0-9]*), display aspect: ([0-9]*\.[0-9]*), ([0-9]*\.[0-9]*) fps");\r
+ //size: 720x576, pixel aspect: 16/15, display aspect: 1.33, 25.000 fps\r
\r
- try\r
- {\r
- thisTitle.m_audioTracks.AddRange(AudioTrack.ParseList(output));\r
- }\r
- catch (Exception exc)\r
- {\r
- if (Properties.Settings.Default.GuiDebug == "Checked")\r
- {\r
- MessageBox.Show("Title.cs - Audio EXC " + exc.ToString());\r
- }\r
- }\r
-\r
- try\r
- {\r
- thisTitle.m_subtitles.AddRange(Subtitle.ParseList(output));\r
- }\r
- catch (Exception exc)\r
- {\r
- if (Properties.Settings.Default.GuiDebug == "Checked")\r
- {\r
- MessageBox.Show("Title.cs - Subtitles EXC " + exc.ToString());\r
- }\r
- }\r
- }\r
- catch (Exception exc)\r
+ if (m.Success)\r
{\r
- if (Properties.Settings.Default.GuiDebug == "Checked")\r
- {\r
- MessageBox.Show("Title.cs - Parse " + exc.ToString());\r
- }\r
+ thisTitle.m_resolution = new Size(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value));\r
+ thisTitle.m_parVal = new Size(int.Parse(m.Groups[3].Value), int.Parse(m.Groups[4].Value));\r
+ thisTitle.m_aspectRatio = float.Parse(m.Groups[5].Value, Culture);\r
}\r
- \r
- \r
+\r
+ // Get autocrop region for this title\r
+ m = Regex.Match(output.ReadLine(), @"^ \+ autocrop: ([0-9]*)/([0-9]*)/([0-9]*)/([0-9]*)");\r
+ if (m.Success)\r
+ thisTitle.m_autoCrop = new int[]\r
+ {\r
+ int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value),\r
+ int.Parse(m.Groups[3].Value), int.Parse(m.Groups[4].Value)\r
+ };\r
+\r
+ thisTitle.m_chapters.AddRange(Chapter.ParseList(output));\r
+\r
+ thisTitle.m_audioTracks.AddRange(AudioTrack.ParseList(output));\r
+\r
+ thisTitle.m_subtitles.AddRange(Subtitle.ParseList(output));\r
+\r
return thisTitle;\r
}\r
\r
public static Title[] ParseList(string output)\r
{\r
- List<Title> titles = new List<Title>();\r
- try\r
- {\r
- StringReader sr = new StringReader(output);\r
- while ((char)sr.Peek() == '+')\r
- {\r
- titles.Add(Title.Parse(sr));\r
- }\r
- }\r
- catch (Exception exc)\r
+ var titles = new List<Title>();\r
+ var sr = new StringReader(output);\r
+\r
+ while (sr.Peek() == '+' || sr.Peek() == ' ')\r
{\r
- if (Properties.Settings.Default.GuiDebug == "Checked")\r
- {\r
- MessageBox.Show("Title.cs - ParseList " + exc.ToString());\r
- }\r
+ // If the the character is a space, then chances are the line\r
+ if (sr.Peek() == ' ') // If the character is a space, then chances are it's the combing detected line.\r
+ sr.ReadLine(); // Skip over it\r
+ else\r
+ titles.Add(Parse(sr));\r
}\r
+\r
return titles.ToArray();\r
}\r
}\r
-}\r
+}
\ No newline at end of file