OSDN Git Service

WinGui:
[handbrake-jp/handbrake-jp-git.git] / win / C# / Functions / QueryParser.cs
1 /*  QueryParser.cs $\r
2     This file is part of the HandBrake source code.\r
3     Homepage: <http://handbrake.fr>.\r
4     It may be used under the terms of the GNU General Public License. */\r
5 \r
6 namespace Handbrake.Functions\r
7 {\r
8     using System;\r
9     using System.Collections;\r
10     using System.Globalization;\r
11     using System.Text.RegularExpressions;\r
12     using System.Windows.Forms;\r
13     using Model;\r
14 \r
15     /// <summary>\r
16     /// Parse a CLI Query\r
17     /// </summary>\r
18     public class QueryParser\r
19     {\r
20         /// <summary>\r
21         /// The Culture\r
22         /// </summary>\r
23         private static readonly CultureInfo Culture = new CultureInfo("en-US", false);\r
24 \r
25         #region Varibles\r
26 \r
27         // Source\r
28         public int DVDTitle { get; set; }\r
29         public int DVDChapterStart { get; set; }\r
30         public int DVDChapterFinish { get; set; }\r
31 \r
32         // Output Settings\r
33         public string Format { get; set; }\r
34         public bool LargeMP4 { get; set; }\r
35         public bool IpodAtom { get; set; }\r
36         public bool OptimizeMP4 { get; set; }\r
37 \r
38         // Picture Settings\r
39         public int Width { get; set; }\r
40         public int Height { get; set; }\r
41         public int MaxWidth { get; set; }\r
42         public int MaxHeight { get; set; }\r
43         public string CropValues { get; set; }\r
44         public string CropTop { get; set; }\r
45         public string CropBottom { get; set; }\r
46         public string CropLeft { get; set; }\r
47         public string CropRight { get; set; }\r
48         public int AnamorphicMode { get; set; }\r
49         public bool KeepDisplayAsect { get; set; }\r
50         public double DisplayWidthValue { get; set; }\r
51         public int PixelAspectWidth { get; set; }\r
52         public int PixelAspectHeight { get; set; }\r
53         public int AnamorphicModulus { get; set; }\r
54 \r
55         // Video Filters\r
56         public string DeTelecine { get; set; }\r
57         public int DeBlock { get; set; }\r
58         public string DeInterlace { get; set; }\r
59         public string DeNoise { get; set; }\r
60         public string Decomb { get; set; }\r
61 \r
62         // Video Settings\r
63         public string VideoEncoder { get; set; }\r
64         public bool Grayscale { get; set; }\r
65         public bool TwoPass { get; set; }\r
66         public bool TurboFirstPass { get; set; }\r
67         public string VideoFramerate { get; set; }\r
68         public string AverageVideoBitrate { get; set; }\r
69         public string VideoTargetSize { get; set; }\r
70         public float VideoQuality { get; set; }\r
71 \r
72         // Audio Settings\r
73         public ArrayList AudioInformation { get; set; }\r
74         public string Subtitles { get; set; }\r
75         public bool ForcedSubtitles { get; set; }\r
76 \r
77         // Chapter Markers\r
78         public bool ChapterMarkers { get; set; }\r
79 \r
80         // Other\r
81         public string H264Query { get; set; }\r
82         public bool Verbose { get; set; }\r
83 \r
84         // Preset Information\r
85         public int PresetBuildNumber { get; set; }\r
86         public string PresetDescription { get; set; }\r
87         public string PresetName { get; set; }\r
88         public string Type { get; set; }\r
89         public bool UsesMaxPictureSettings { get; set; }\r
90         public bool UsesPictureFilters { get; set; }\r
91         public bool UsesPictureSettings { get; set; }\r
92 \r
93         #endregion\r
94 \r
95         /// <summary>\r
96         /// Takes in a query which can be in any order and parses it. \r
97         /// All varibles are then set so they can be used elsewhere.\r
98         /// </summary>\r
99         /// <param name="input">A ClI Query</param>\r
100         /// <returns>A Parsed Query</returns>\r
101         public static QueryParser Parse(string input)\r
102         {\r
103             var thisQuery = new QueryParser();\r
104 \r
105             #region Regular Expressions\r
106 \r
107             // Source\r
108             Match title = Regex.Match(input, @"-t ([0-9]*)");\r
109             Match chapters = Regex.Match(input, @"-c ([0-9-]*)");\r
110 \r
111             // Output Settings\r
112             Match format = Regex.Match(input, @"-f ([a-z0-9a-z0-9a-z0-9]*)");\r
113             Match grayscale = Regex.Match(input, @" -g");\r
114             Match largerMp4 = Regex.Match(input, @" -4");\r
115             Match ipodAtom = Regex.Match(input, @" -I");\r
116 \r
117             // Picture Settings Tab\r
118             Match width = Regex.Match(input, @"-w ([0-9]*)");\r
119             Match height = Regex.Match(input, @"-l ([0-9]*)");\r
120             Match maxWidth = Regex.Match(input, @"-X ([0-9]*)");\r
121             Match maxHeight = Regex.Match(input, @"-Y ([0-9]*)");\r
122             Match crop = Regex.Match(input, @"--crop ([0-9]*):([0-9]*):([0-9]*):([0-9]*)");\r
123 \r
124             Match looseAnamorphic = Regex.Match(input, @"--loose-anamorphic");\r
125             Match strictAnamorphic = Regex.Match(input, @"--strict-anamorphic");\r
126             Match customAnamorphic = Regex.Match(input, @"--custom-anamorphic");\r
127 \r
128             Match keepDisplayAsect = Regex.Match(input, @"--keep-display-aspect");\r
129             Match displayWidth = Regex.Match(input, @"--display-width ([0-9*])");\r
130             Match pixelAspect = Regex.Match(input, @"--pixel-aspect ([0-9]*):([0-9]*)");\r
131             Match modulus = Regex.Match(input, @"--modulus ([0-9*])");\r
132 \r
133             // Picture Settings - Filters\r
134             Match decomb = Regex.Match(input, @" --decomb");\r
135             Match decombValue = Regex.Match(input, @" --decomb=\""([a-zA-Z0-9.:]*)\""");\r
136             Match deinterlace = Regex.Match(input, @"--deinterlace=\""([a-zA-Z0-9.:]*)\""");\r
137             Match denoise = Regex.Match(input, @"--denoise=\""([a-zA-Z0-9.:]*)\""");\r
138             Match deblock = Regex.Match(input, @"--deblock=([0-9:]*)");\r
139             Match detelecine = Regex.Match(input, @"--detelecine");\r
140             Match detelecineValue = Regex.Match(input, @" --detelecine=\""([a-zA-Z0-9.:]*)\""");\r
141 \r
142             // Video Settings Tab\r
143             Match videoEncoder = Regex.Match(input, @"-e ([a-zA-Z0-9]*)");\r
144             Match videoFramerate = Regex.Match(input, @"-r ([0-9.]*)");\r
145             Match videoBitrate = Regex.Match(input, @"-b ([0-9]*)");\r
146             Match videoQuality = Regex.Match(input, @"-q ([0-9.]*)");\r
147             Match videoFilesize = Regex.Match(input, @"-S ([0-9.]*)");\r
148             Match twoPass = Regex.Match(input, @" -2");\r
149             Match turboFirstPass = Regex.Match(input, @" -T");\r
150             Match optimizeMP4 = Regex.Match(input, @" -O");\r
151 \r
152             // Audio Settings Tab\r
153             Match noAudio = Regex.Match(input, @"-a none");\r
154             Match audioTracks = Regex.Match(input, @"-a ([0-9,]*)");\r
155             Match audioTrackMixes = Regex.Match(input, @"-6 ([0-9a-zA-Z,]*)");\r
156             Match audioEncoders = Regex.Match(input, @"-E ([a-zA-Z0-9+,]*)");\r
157             Match audioBitrates = Regex.Match(input, @"-B ([0-9a-zA-Z,]*)"); // Auto = a-z\r
158             Match audioSampleRates = Regex.Match(input, @"-R ([0-9a-zA-Z.,]*)"); // Auto = a-z\r
159             Match drcValues = Regex.Match(input, @"-D ([0-9.,]*)");\r
160 \r
161             Match subtitles = Regex.Match(input, @"-s ([0-9a-zA-Z]*)");\r
162             Match subScan = Regex.Match(input, @" -U");\r
163             Match forcedSubtitles = Regex.Match(input, @" -F");\r
164 \r
165             // Chapters Tab\r
166             Match chapterMarkers = Regex.Match(input, @" -m");\r
167             Match chapterMarkersFileMode = Regex.Match(input, @"--markers");\r
168 \r
169             // H264 Tab\r
170             Match x264 = Regex.Match(input, @"-x ([.,/a-zA-Z0-9=:-]*)");\r
171 \r
172             // Program Options\r
173             Match verbose = Regex.Match(input, @" -v");\r
174 \r
175             #endregion\r
176 \r
177             #region Set Varibles\r
178 \r
179             try\r
180             {\r
181                 #region Source Tab\r
182 \r
183                 if (title.Success)\r
184                     thisQuery.DVDTitle = int.Parse(title.ToString().Replace("-t ", string.Empty));\r
185 \r
186                 if (chapters.Success)\r
187                 {\r
188                     string[] actTitles = chapters.ToString().Replace("-c ", string.Empty).Split('-');\r
189                     thisQuery.DVDChapterStart = int.Parse(actTitles[0]);\r
190                     if (actTitles.Length > 1)\r
191                     {\r
192                         thisQuery.DVDChapterFinish = int.Parse(actTitles[1]);\r
193                     }\r
194 \r
195                     if ((thisQuery.DVDChapterStart == 1) && (thisQuery.DVDChapterFinish == 0))\r
196                         thisQuery.DVDChapterFinish = thisQuery.DVDChapterStart;\r
197                 }\r
198 \r
199                 #endregion\r
200 \r
201                 #region Output Settings\r
202 \r
203                 if (format.Success)\r
204                     thisQuery.Format = format.ToString().Replace("-f ", string.Empty);\r
205                 thisQuery.LargeMP4 = largerMp4.Success;\r
206                 thisQuery.IpodAtom = ipodAtom.Success;\r
207                 thisQuery.OptimizeMP4 = optimizeMP4.Success;\r
208 \r
209                 #endregion\r
210 \r
211                 #region Picture Tab\r
212 \r
213                 if (width.Success)\r
214                     thisQuery.Width = int.Parse(width.Groups[0].Value.Replace("-w ", string.Empty));\r
215 \r
216                 if (height.Success)\r
217                     thisQuery.Height = int.Parse(height.Groups[0].Value.Replace("-l ", string.Empty));\r
218 \r
219                 if (maxWidth.Success)\r
220                     thisQuery.MaxWidth = int.Parse(maxWidth.Groups[0].Value.Replace("-X ", string.Empty));\r
221 \r
222                 if (maxHeight.Success)\r
223                     thisQuery.MaxHeight = int.Parse(maxHeight.Groups[0].Value.Replace("-Y ", string.Empty));\r
224 \r
225                 if (crop.Success)\r
226                 {\r
227                     thisQuery.CropValues = crop.ToString().Replace("--crop ", string.Empty);\r
228                     string[] actCropValues = thisQuery.CropValues.Split(':');\r
229                     thisQuery.CropTop = actCropValues[0];\r
230                     thisQuery.CropBottom = actCropValues[1];\r
231                     thisQuery.CropLeft = actCropValues[2];\r
232                     thisQuery.CropRight = actCropValues[3];\r
233                 }\r
234 \r
235                 if (strictAnamorphic.Success)\r
236                     thisQuery.AnamorphicMode = 1;\r
237                 else if (looseAnamorphic.Success)\r
238                     thisQuery.AnamorphicMode = 2;\r
239                 else if (customAnamorphic.Success)\r
240                     thisQuery.AnamorphicMode = 3;\r
241                 else\r
242                     thisQuery.AnamorphicMode = 0;\r
243 \r
244                 thisQuery.KeepDisplayAsect = keepDisplayAsect.Success;\r
245 \r
246                 if (displayWidth.Success)\r
247                     thisQuery.DisplayWidthValue =\r
248                         double.Parse(displayWidth.Groups[0].Value.Replace("--display-width ", string.Empty));\r
249 \r
250                 if (pixelAspect.Success)\r
251                     thisQuery.PixelAspectWidth = int.Parse(pixelAspect.Groups[1].Value.Replace("--pixel-aspect ", string.Empty));\r
252 \r
253                 if (pixelAspect.Success && pixelAspect.Groups.Count >= 3)\r
254                     thisQuery.PixelAspectHeight = int.Parse(pixelAspect.Groups[2].Value.Replace("--pixel-aspect ", string.Empty));\r
255 \r
256                 if (modulus.Success)\r
257                     thisQuery.AnamorphicModulus = int.Parse(modulus.Groups[0].Value.Replace("--modulus ", string.Empty));\r
258 \r
259                 #endregion\r
260 \r
261                 #region Filters\r
262 \r
263                 thisQuery.Decomb = "Off";\r
264                 if (decomb.Success)\r
265                 {\r
266                     thisQuery.Decomb = "Default";\r
267                     if (decombValue.Success)\r
268                         thisQuery.Decomb = decombValue.ToString().Replace("--decomb=", string.Empty).Replace("\"", string.Empty);\r
269                 }\r
270 \r
271                 thisQuery.DeInterlace = "Off";\r
272                 if (deinterlace.Success)\r
273                 {\r
274                     thisQuery.DeInterlace = deinterlace.ToString().Replace("--deinterlace=", string.Empty).Replace("\"", string.Empty);\r
275                     thisQuery.DeInterlace =\r
276                         thisQuery.DeInterlace.Replace("fast", "Fast").Replace("slow", "Slow").Replace("slower", "Slower");\r
277                     thisQuery.DeInterlace = thisQuery.DeInterlace.Replace("slowest", "Slowest");\r
278                 }\r
279 \r
280                 thisQuery.DeNoise = "Off";\r
281                 if (denoise.Success)\r
282                 {\r
283                     thisQuery.DeNoise = denoise.ToString().Replace("--denoise=", string.Empty).Replace("\"", string.Empty);\r
284                     thisQuery.DeNoise =\r
285                         thisQuery.DeNoise.Replace("weak", "Weak").Replace("medium", "Medium").Replace("strong", "Strong");\r
286                 }\r
287 \r
288                 string deblockValue = string.Empty;\r
289                 thisQuery.DeBlock = 0;\r
290                 if (deblock.Success)\r
291                     deblockValue = deblock.ToString().Replace("--deblock=", string.Empty);\r
292 \r
293                 int dval = 0;\r
294                 if (deblockValue != string.Empty)\r
295                     int.TryParse(deblockValue, out dval);\r
296                 thisQuery.DeBlock = dval;\r
297 \r
298                 thisQuery.DeTelecine = "Off";\r
299                 if (detelecine.Success)\r
300                 {\r
301                     thisQuery.DeTelecine = "Default";\r
302                     if (detelecineValue.Success)\r
303                         thisQuery.DeTelecine = detelecineValue.ToString().Replace("--detelecine=", string.Empty).Replace("\"", string.Empty);\r
304                 }\r
305 \r
306                 #endregion\r
307 \r
308                 #region Video Settings Tab\r
309 \r
310                 string videoEncoderConvertion = videoEncoder.ToString().Replace("-e ", string.Empty);\r
311                 switch (videoEncoderConvertion)\r
312                 {\r
313                     case "ffmpeg":\r
314                         videoEncoderConvertion = "MPEG-4 (FFmpeg)";\r
315                         break;\r
316                     case "x264":\r
317                         videoEncoderConvertion = "H.264 (x264)";\r
318                         break;\r
319                     case "theora":\r
320                         videoEncoderConvertion = "VP3 (Theora)";\r
321                         break;\r
322                     default:\r
323                         videoEncoderConvertion = "MPEG-4 (FFmpeg)";\r
324                         break;\r
325                 }\r
326                 thisQuery.VideoEncoder = videoEncoderConvertion;\r
327                 thisQuery.VideoFramerate = videoFramerate.Success\r
328                                                ? videoFramerate.ToString().Replace("-r ", string.Empty)\r
329                                                : "Same as source";\r
330                 thisQuery.Grayscale = grayscale.Success;\r
331                 thisQuery.TwoPass = twoPass.Success;\r
332                 thisQuery.TurboFirstPass = turboFirstPass.Success;\r
333 \r
334                 if (videoBitrate.Success)\r
335                     thisQuery.AverageVideoBitrate = videoBitrate.ToString().Replace("-b ", string.Empty);\r
336                 if (videoFilesize.Success)\r
337                     thisQuery.VideoTargetSize = videoFilesize.ToString().Replace("-S ", string.Empty);\r
338 \r
339                 if (videoQuality.Success)\r
340                 {\r
341                     float qConvert = float.Parse(videoQuality.ToString().Replace("-q ", string.Empty), Culture);\r
342                     thisQuery.VideoQuality = qConvert;\r
343                 }\r
344                 else\r
345                     thisQuery.VideoQuality = -1;\r
346 \r
347                 #endregion\r
348 \r
349                 #region Audio Tab\r
350 \r
351                 // Find out how many tracks we need to add by checking how many encoders or audio tracks are selected.\r
352                 int encoderCount = 0;\r
353                 if (audioEncoders.Success)\r
354                 {\r
355                     string[] audioDataCounters = audioEncoders.ToString().Replace("-E ", string.Empty).Split(',');\r
356                     encoderCount = audioDataCounters.Length;\r
357                 }\r
358 \r
359                 // Get the data from the regular expression results\r
360                 string[] trackData = null;\r
361                 string[] trackMixes = null;\r
362                 string[] trackEncoders = null;\r
363                 string[] trackBitrates = null;\r
364                 string[] trackSamplerates = null;\r
365                 string[] trackDRCvalues = null;\r
366 \r
367                 if (audioTracks.Success)\r
368                     trackData = audioTracks.ToString().Replace("-a ", string.Empty).Split(',');\r
369                 if (audioTrackMixes.Success)\r
370                     trackMixes = audioTrackMixes.ToString().Replace("-6 ", string.Empty).Split(',');\r
371                 if (audioEncoders.Success)\r
372                     trackEncoders = audioEncoders.ToString().Replace("-E ", string.Empty).Split(',');\r
373                 if (audioBitrates.Success)\r
374                     trackBitrates = audioBitrates.ToString().Replace("-B ", string.Empty).Split(',');\r
375                 if (audioSampleRates.Success)\r
376                     trackSamplerates = audioSampleRates.ToString().Replace("-R ", string.Empty).Split(',');\r
377                 if (drcValues.Success)\r
378                     trackDRCvalues = drcValues.ToString().Replace("-D ", string.Empty).Split(',');\r
379 \r
380                 // Create new Audio Track Classes and store them in the ArrayList\r
381                 ArrayList allAudioTrackInfo = new ArrayList();\r
382                 for (int x = 0; x < encoderCount; x++)\r
383                 {\r
384                     AudioTrack track = new AudioTrack();\r
385                     if (trackData != null)\r
386                         if (trackData.Length >= (x + 1)) // Audio Track\r
387                             track.Track = trackData[x].Trim();\r
388 \r
389                     if (trackMixes != null)\r
390                         if (trackMixes.Length >= (x + 1)) // Audio Mix\r
391                             track.MixDown = GetMixDown(trackMixes[x].Trim());\r
392 \r
393                     if (trackEncoders != null)\r
394                         if (trackEncoders.Length >= (x + 1)) // Audio Mix\r
395                             track.Encoder = GetAudioEncoder(trackEncoders[x].Trim());\r
396 \r
397                     if (trackBitrates != null)\r
398                         if (trackBitrates.Length >= (x + 1)) // Audio Encoder\r
399                             track.Bitrate = trackBitrates[x].Trim() == "auto" ? "Auto" : trackBitrates[x].Trim();\r
400 \r
401                     if (trackSamplerates != null)\r
402                         if (trackSamplerates.Length >= (x + 1)) // Audio SampleRate\r
403                             track.SampleRate = trackSamplerates[x].Trim() == "0" ? "Auto" : trackSamplerates[x].Trim();\r
404 \r
405                     if (trackDRCvalues != null)\r
406                         if (trackDRCvalues.Length >= (x + 1)) // Audio DRC Values\r
407                             track.DRC = trackDRCvalues[x].Trim();\r
408 \r
409                     allAudioTrackInfo.Add(track);\r
410                 }\r
411                 thisQuery.AudioInformation = allAudioTrackInfo;\r
412 \r
413                 // Subtitle Stuff\r
414                 if (subtitles.Success)\r
415                     thisQuery.Subtitles = subtitles.ToString().Replace("-s ", string.Empty);\r
416                 else\r
417                     thisQuery.Subtitles = subScan.Success ? "Autoselect" : "None";\r
418 \r
419                 thisQuery.ForcedSubtitles = forcedSubtitles.Success;\r
420 \r
421                 #endregion\r
422 \r
423                 #region Chapters Tab\r
424 \r
425                 if (chapterMarkersFileMode.Success || chapterMarkers.Success)\r
426                     thisQuery.ChapterMarkers = true;\r
427 \r
428                 #endregion\r
429 \r
430                 #region H.264 and other\r
431 \r
432                 if (x264.Success)\r
433                     thisQuery.H264Query = x264.ToString().Replace("-x ", string.Empty);\r
434 \r
435                 thisQuery.Verbose = verbose.Success;\r
436 \r
437                 #endregion\r
438             }\r
439             catch (Exception exc)\r
440             {\r
441                 MessageBox.Show("An error has occured in the Query Parser.\n\n" + exc, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);\r
442             }\r
443 \r
444             #endregion\r
445 \r
446             return thisQuery;\r
447         }\r
448 \r
449         /// <summary>\r
450         /// Get the GUI equiv to a CLI mixdown\r
451         /// </summary>\r
452         /// <param name="mixdown">The Audio Mixdown</param>\r
453         /// <returns>The GUI representation of the mixdown</returns>\r
454         private static string GetMixDown(string mixdown)\r
455         {\r
456             switch (mixdown.Trim())\r
457             {\r
458                 case "mono":\r
459                     return "Mono";\r
460                 case "stereo":\r
461                     return "Stereo";\r
462                 case "dpl1":\r
463                     return "Dolby Surround";\r
464                 case "dpl2":\r
465                     return "Dolby Pro Logic II";\r
466                 case "6ch":\r
467                     return "6 Channel Discrete";\r
468                 default:\r
469                     return "Automatic";\r
470             }\r
471         }\r
472 \r
473         /// <summary>\r
474         /// Get the GUI equiv to a CLI audio encoder\r
475         /// </summary>\r
476         /// <param name="audioEnc">The Audio Encoder</param>\r
477         /// <returns>The GUI representation of that audio encoder</returns>\r
478         private static string GetAudioEncoder(string audioEnc)\r
479         {\r
480             switch (audioEnc)\r
481             {\r
482                 case "faac":\r
483                     return "AAC (faac)";\r
484                 case "lame":\r
485                     return "MP3 (lame)";\r
486                 case "vorbis":\r
487                     return "Vorbis (vorbis)";\r
488                 case "ac3":\r
489                     return "AC3 Passthru";\r
490                 case "dts":\r
491                     return "DTS Passthru";\r
492                 default:\r
493                     return "AAC (faac)";\r
494             }\r
495         }\r
496     }\r
497 }