3 This file is part of the HandBrake source code.
\r
4 Homepage: <http://handbrake.fr>.
\r
5 It may be used under the terms of the GNU General Public License. */
\r
8 using System.Collections.Generic;
\r
10 using System.Text.RegularExpressions;
\r
11 using System.Windows.Forms;
\r
13 namespace Handbrake.Functions
\r
18 // All the Main Window GUI options
\r
22 private string q_source;
\r
24 /// Returns a String
\r
25 /// Full path of the source.
\r
27 public string Source
\r
31 return this.q_source;
\r
34 private int q_dvdTitle;
\r
36 /// Returns an Integer
\r
37 /// DVD Title number.
\r
43 return this.q_dvdTitle;
\r
47 private int q_chaptersStart;
\r
50 /// DVD Chapter number or chapter range.
\r
52 public int DVDChapterStart
\r
56 return this.q_chaptersStart;
\r
60 private int q_chaptersFinish;
\r
63 /// DVD Chapter number or chapter range.
\r
65 public int DVDChapterFinish
\r
69 return this.q_chaptersFinish;
\r
76 private string q_destination;
\r
78 /// Returns a String
\r
79 /// Full path of the destination.
\r
81 public string Destination
\r
85 return this.q_destination;
\r
89 private string q_format;
\r
91 /// Returns a String
\r
92 /// Full path of the destination.
\r
94 public string Format
\r
98 return this.q_format;
\r
102 private string q_videoEncoder;
\r
104 /// Returns an String
\r
105 /// The Video Encoder used.
\r
107 public string VideoEncoder
\r
111 return this.q_videoEncoder;
\r
116 #region Picture Settings
\r
117 private int q_videoWidth;
\r
120 /// The selected Width for the encoding.
\r
126 return this.q_videoWidth;
\r
130 private int q_videoHeight;
\r
133 /// The selected Height for the encoding.
\r
139 return this.q_videoHeight;
\r
143 private string q_cropValues;
\r
145 /// Returns an String
\r
146 /// Cropping values.
\r
148 public string CropValues
\r
152 return this.q_cropValues;
\r
156 private string q_croptop;
\r
158 /// Returns an String
\r
159 /// Cropping values.
\r
161 public string CropTop
\r
165 return this.q_croptop;
\r
169 private string q_cropbottom;
\r
171 /// Returns an String
\r
172 /// Cropping values.
\r
174 public string CropBottom
\r
178 return this.q_cropbottom;
\r
182 private string q_cropLeft;
\r
184 /// Returns an String
\r
185 /// Cropping values.
\r
187 public string CropLeft
\r
191 return this.q_cropLeft;
\r
195 private string q_cropRight;
\r
197 /// Returns an String
\r
198 /// Cropping values.
\r
200 public string CropRight
\r
204 return this.q_cropRight;
\r
208 private Boolean q_detelecine;
\r
210 /// Returns a boolean to indicate wither DeTelecine is on or off
\r
212 public Boolean DeTelecine
\r
216 return this.q_detelecine;
\r
220 private Boolean q_vfr;
\r
222 /// Returns a boolean to indicate wither DeTelecine is on or off
\r
232 private Boolean q_deBlock;
\r
234 /// Returns a boolean to indicate wither DeBlock is on or off.
\r
236 public Boolean DeBlock
\r
240 return this.q_deBlock;
\r
244 private string q_deinterlace;
\r
246 /// Returns a string with the De-Interlace option used.
\r
248 public string DeInterlace
\r
252 return this.q_deinterlace;
\r
256 private string q_denoise;
\r
258 /// Returns a string with the DeNoise option used.
\r
260 public string DeNoise
\r
264 return this.q_denoise;
\r
268 private Boolean q_anamorphic;
\r
270 /// Returns a boolean to indicate wither Anamorphic is on or off.
\r
272 public Boolean Anamorphic
\r
276 return this.q_anamorphic;
\r
280 private Boolean q_looseAnamorphic;
\r
282 /// Returns a boolean to indicate wither Anamorphic is on or off.
\r
284 public Boolean LooseAnamorphic
\r
288 return this.q_looseAnamorphic;
\r
292 private Boolean q_chapterMarkers;
\r
294 /// Returns a boolean to indicate wither Chapter Markers is on or off.
\r
296 public Boolean ChapterMarkers
\r
300 return this.q_chapterMarkers;
\r
305 #region Video Settings
\r
306 private Boolean q_grayscale;
\r
308 /// Returns a boolean to indicate wither Grayscale is on or off.
\r
310 public Boolean Grayscale
\r
314 return this.q_grayscale;
\r
318 private Boolean q_twoPass;
\r
320 /// Returns a boolean to indicate wither Two Pass Encoding is on or off.
\r
322 public Boolean TwoPass
\r
326 return this.q_twoPass;
\r
330 private Boolean q_turboFirst;
\r
332 /// Returns a boolean to indicate wither Chapter Markers is on or off.
\r
334 public Boolean TurboFirstPass
\r
338 return this.q_turboFirst;
\r
342 private Boolean q_largeMp4;
\r
344 /// Returns a boolean to indicate wither Larger MP4 files is on or off.
\r
346 public Boolean LargeMP4
\r
350 return this.q_largeMp4;
\r
354 private Boolean q_ipodAtom;
\r
356 /// Returns a boolean to indicate wither Larger MP4 files is on or off.
\r
358 public Boolean IpodAtom
\r
362 return this.q_ipodAtom;
\r
366 private Boolean q_optimizeMp4;
\r
368 /// Returns a boolean to indicate wither Larger MP4 files is on or off.
\r
370 public Boolean OptimizeMP4
\r
374 return this.q_optimizeMp4;
\r
378 private string q_videoFramerate;
\r
380 /// Returns a string with the video Framerate
\r
382 public string VideoFramerate
\r
386 return this.q_videoFramerate;
\r
390 private string q_avgBitrate;
\r
392 /// Returns a string with the average video bitrate
\r
394 public string AverageVideoBitrate
\r
398 return this.q_avgBitrate;
\r
402 private string q_videoTargetSize;
\r
404 /// Returns a string with the video target size
\r
406 public string VideoTargetSize
\r
410 return this.q_videoTargetSize;
\r
414 private int q_videoQuality;
\r
416 /// Returns a int with the video quality value
\r
418 public int VideoQuality
\r
422 return this.q_videoQuality;
\r
428 #region Audio Settings
\r
429 private string q_audioTrack1;
\r
431 /// Returns a string with the First selected Audio track
\r
433 public string AudioTrack1
\r
437 return this.q_audioTrack1;
\r
441 private string q_audioTrack2;
\r
443 /// Returns a string with the First selected Audio track
\r
445 public string AudioTrack2
\r
449 return this.q_audioTrack2;
\r
453 private string q_audioTrackMix1;
\r
455 /// Returns a string with the First selected Audio track Mix
\r
457 public string AudioTrackMix1
\r
461 return this.q_audioTrackMix1;
\r
465 private string q_audioTrackMix2;
\r
467 /// Returns a string with the First selected Audio track Mix
\r
469 public string AudioTrackMix2
\r
473 return this.q_audioTrackMix2;
\r
477 private string q_audioEncoder1;
\r
479 /// Returns an String
\r
480 /// The Audio Encoder used.
\r
482 public string AudioEncoder1
\r
486 return this.q_audioEncoder1;
\r
490 private string q_audioEncoder2;
\r
492 /// Returns an String
\r
493 /// The Audio Encoder used.
\r
495 public string AudioEncoder2
\r
499 return this.q_audioEncoder2;
\r
503 private string q_audioBitrate1;
\r
505 /// Returns a string with the audio bitrate
\r
507 public string AudioBitrate1
\r
511 return this.q_audioBitrate1;
\r
515 private string q_audioBitrate2;
\r
517 /// Returns a string with the audio bitrate
\r
519 public string AudioBitrate2
\r
523 return this.q_audioBitrate2;
\r
527 private string q_audioSamplerate1;
\r
529 /// Returns a string with the audio sample rate
\r
531 public string AudioSamplerate1
\r
535 return this.q_audioSamplerate1;
\r
539 private string q_audioSamplerate2;
\r
541 /// Returns a string with the audio sample rate
\r
543 public string AudioSamplerate2
\r
547 return this.q_audioSamplerate2;
\r
551 private double q_drc;
\r
553 /// Returns a string with the selected subtitle track
\r
563 private string q_subtitles;
\r
565 /// Returns a string with the selected subtitle track
\r
567 public string Subtitles
\r
571 return this.q_subtitles;
\r
575 private Boolean q_forcedSubs;
\r
577 /// Returns a string with the selected subtitle track
\r
579 public Boolean ForcedSubtitles
\r
583 return this.q_forcedSubs;
\r
590 private string q_h264;
\r
592 /// Returns a string with the Advanced H264 query string
\r
594 public string H264Query
\r
598 return this.q_h264;
\r
601 private Boolean q_verbose;
\r
603 /// Returns a string with the Advanced H264 query string
\r
605 public Boolean Verbose
\r
609 return this.q_verbose;
\r
616 // Takes in a query which can be in any order and parses it. All varibles are then set so they can be used elsewhere.
\r
617 public static QueryParser Parse(String input)
\r
619 QueryParser thisQuery = new QueryParser();
\r
621 #region Regular Expressions
\r
623 Regex r1 = new Regex(@"(-i)(?:\s\"")([a-zA-Z0-9:\\\s\.]+)(?:\"")");
\r
624 Match source = r1.Match(input.Replace('"', '\"'));
\r
625 Match title = Regex.Match(input, @"-t ([0-9]*)");
\r
626 Match chapters = Regex.Match(input, @"-c ([0-9-]*)");
\r
627 Match format = Regex.Match(input, @"-f ([a-z0-9a-z0-9a-z0-9]*)");
\r
630 Regex r2 = new Regex(@"(-o)(?:\s\"")([a-zA-Z0-9_\-:\\\s\.]+)(?:\"")");
\r
631 Match destination = r2.Match(input.Replace('"', '\"'));
\r
632 Match videoEncoder = Regex.Match(input, @"-e ([a-zA-Z0-9]*)");
\r
634 //Picture Settings Tab
\r
635 Match width = Regex.Match(input, @"-w ([0-9]*)");
\r
636 Match height = Regex.Match(input, @"-l ([0-9]*)");
\r
637 Match deinterlace = Regex.Match(input, @"--deinterlace=([a-z]*)");
\r
638 Match denoise = Regex.Match(input, @"--denoise=([a-z]*)");
\r
639 Match deblock = Regex.Match(input, @"--deblock");
\r
640 Match detelecine = Regex.Match(input, @"--detelecine");
\r
641 Match anamorphic = Regex.Match(input, @"-p ");
\r
642 Match chapterMarkers = Regex.Match(input, @"-m");
\r
643 Match crop = Regex.Match(input, @"--crop ([0-9]):([0-9]):([0-9]):([0-9])");
\r
644 Match vfr = Regex.Match(input, @"-V");
\r
645 Match lanamorphic = Regex.Match(input, @"-P");
\r
647 //Video Settings Tab
\r
648 Match videoFramerate = Regex.Match(input, @"-r ([0-9]*)");
\r
649 Match videoBitrate = Regex.Match(input, @"-b ([0-9]*)");
\r
650 Match videoQuality = Regex.Match(input, @"-q ([0-9.]*)");
\r
651 Match videoFilesize = Regex.Match(input, @"-S ([0-9.]*)");
\r
652 Match twoPass = Regex.Match(input, @"-2");
\r
653 Match turboFirstPass = Regex.Match(input, @"-T");
\r
654 Match grayscale = Regex.Match(input, @"-g");
\r
655 Match largerMp4 = Regex.Match(input, @"-4");
\r
656 Match ipodAtom = Regex.Match(input, @"-I");
\r
657 Match optimizeMP4 = Regex.Match(input, @"-O");
\r
659 //Audio Settings Tab
\r
660 Match audioTrack1 = Regex.Match(input, @"-a ([0-9]*)");
\r
661 Match audioTrack2 = Regex.Match(input, @"-a ([0-9]*),([0-9]*)");
\r
662 Match audioTrack1Mix = Regex.Match(input, @"-6 ([0-9a-z0-9]*)");
\r
663 Match audioTrack2Mix = Regex.Match(input, @"-6 ([0-9a-z0-9]*),([0-9a-z0-9]*)");
\r
664 Match audioEncoder1 = Regex.Match(input, @"-E ([a-zA-Z0-9+]*)");
\r
665 Match audioEncoder2 = Regex.Match(input, @"-E ([a-zA-Z0-9+]*),([a-zA-Z0-9+]*)");
\r
666 Match audioBitrate1 = Regex.Match(input, @"-B ([0-9]*)");
\r
667 Match audioBitrate2 = Regex.Match(input, @"-B ([0-9]*),([0-9]*)");
\r
668 Match audioSampleRate1 = Regex.Match(input, @"-R ([0-9.]*)");
\r
669 Match audioSampleRate2 = Regex.Match(input, @"-R ([0-9.]*),([0-9.]*)");
\r
671 Match drc = Regex.Match(input, @"-D ([0-9.]*)");
\r
672 Match subtitles = Regex.Match(input, @"-s ([0-9a-zA-Z]*)");
\r
673 Match subScan = Regex.Match(input, @"-U");
\r
674 Match forcedSubtitles = Regex.Match(input, @"-F");
\r
677 Match x264 = Regex.Match(input, @"-x ([,a-zA-Z0-9=:-]*)");
\r
680 Match verbose = Regex.Match(input, @"-v");
\r
683 #region Set Varibles
\r
691 thisQuery.q_source = source.ToString().Replace("-i ", "").Replace("\"", "");
\r
692 if (title.Success != false)
\r
693 thisQuery.q_dvdTitle = int.Parse(title.ToString().Replace("-t ", ""));
\r
695 if (chapters.Success != false)
\r
697 string[] actTitles = new string[2];
\r
698 actTitles = chapters.ToString().Replace("-c ", "").Split('-');
\r
699 thisQuery.q_chaptersStart = int.Parse(actTitles[0]);
\r
700 if (actTitles.Length > 1)
\r
702 thisQuery.q_chaptersFinish = int.Parse(actTitles[1]);
\r
705 if ((thisQuery.q_chaptersStart == 1) && (thisQuery.q_chaptersFinish == 0))
\r
706 thisQuery.q_chaptersFinish = thisQuery.q_chaptersStart;
\r
709 if (format.Success != false)
\r
710 thisQuery.q_format = format.ToString().Replace("-f ", "");
\r
717 #region Destination
\r
718 thisQuery.q_destination = destination.ToString().Replace("-o ", "").Replace("\"", "");
\r
720 string videoEncoderConvertion;
\r
721 string audioEncoderConvertion;
\r
723 videoEncoderConvertion = videoEncoder.ToString().Replace("-e ", "");
\r
724 switch (videoEncoderConvertion)
\r
727 videoEncoderConvertion = "Mpeg 4";
\r
730 videoEncoderConvertion = "Xvid";
\r
733 videoEncoderConvertion = "H.264";
\r
736 videoEncoderConvertion = "H.264 Baseline 1.3";
\r
739 videoEncoderConvertion = "H.264 (iPod)";
\r
742 videoEncoderConvertion = "Mpeg 4";
\r
745 thisQuery.q_videoEncoder = videoEncoderConvertion;
\r
750 * Picture Settings Tab
\r
752 #region Picture Tab
\r
754 if (width.Success != false)
\r
755 thisQuery.q_videoWidth = int.Parse(width.ToString().Replace("-w ", ""));
\r
757 if (height.Success != false)
\r
758 thisQuery.q_videoHeight = int.Parse(height.ToString().Replace("-l ", ""));
\r
761 if (crop.Success != false)
\r
763 thisQuery.q_cropValues = crop.ToString().Replace("--crop ", "");
\r
764 string[] actCropValues = new string[3];
\r
765 actCropValues = thisQuery.q_cropValues.Split(':');
\r
766 thisQuery.q_croptop = actCropValues[0];
\r
767 thisQuery.q_cropbottom = actCropValues[1];
\r
768 thisQuery.q_cropLeft = actCropValues[2];
\r
769 thisQuery.q_cropRight = actCropValues[3];
\r
772 thisQuery.q_detelecine = detelecine.Success;
\r
773 thisQuery.q_deBlock = deblock.Success;
\r
775 thisQuery.q_deinterlace = "None";
\r
776 if (deinterlace.Success != false)
\r
778 switch (deinterlace.ToString().Replace("--deinterlace=", ""))
\r
781 thisQuery.q_deinterlace = "Fast";
\r
784 thisQuery.q_deinterlace = "Slow";
\r
787 thisQuery.q_deinterlace = "Slower";
\r
790 thisQuery.q_deinterlace = "Slowest";
\r
793 thisQuery.q_deinterlace = "None";
\r
798 thisQuery.q_denoise = "None";
\r
799 if (denoise.Success != false)
\r
801 switch (denoise.ToString().Replace("--denoise=", ""))
\r
804 thisQuery.q_denoise = "Weak";
\r
807 thisQuery.q_denoise = "Medium";
\r
810 thisQuery.q_denoise = "Strong";
\r
813 thisQuery.q_denoise = "None";
\r
818 thisQuery.q_anamorphic = anamorphic.Success;
\r
819 thisQuery.q_chapterMarkers = chapterMarkers.Success;
\r
820 thisQuery.q_vfr = vfr.Success;
\r
821 thisQuery.q_looseAnamorphic = lanamorphic.Success;
\r
826 * Video Settings Tab
\r
829 thisQuery.q_grayscale = grayscale.Success;
\r
830 thisQuery.q_twoPass = twoPass.Success;
\r
831 thisQuery.q_turboFirst = turboFirstPass.Success;
\r
832 thisQuery.q_largeMp4 = largerMp4.Success;
\r
833 if (videoFramerate.Success != false)
\r
834 thisQuery.q_videoFramerate = videoFramerate.ToString().Replace("-r ", "");
\r
836 thisQuery.q_videoFramerate = "Same as source";
\r
838 if (videoBitrate.Success != false)
\r
839 thisQuery.q_avgBitrate = videoBitrate.ToString().Replace("-b ", "");
\r
840 if (videoFilesize.Success != false)
\r
841 thisQuery.q_videoTargetSize = videoFilesize.ToString().Replace("-S ", "");
\r
843 double qConvert = 0;
\r
844 if (videoQuality.Success != false)
\r
846 qConvert = double.Parse(videoQuality.ToString().Replace("-q ", ""), Functions.CLI.Culture) * 100;
\r
847 qConvert = System.Math.Ceiling(qConvert);
\r
848 thisQuery.q_videoQuality = int.Parse(qConvert.ToString());
\r
850 thisQuery.q_ipodAtom = ipodAtom.Success;
\r
851 thisQuery.q_optimizeMp4 = optimizeMP4.Success;
\r
856 * Audio Settings Tab
\r
860 if (audioTrack1.Success != false)
\r
861 thisQuery.q_audioTrack1 = audioTrack1.ToString().Replace("-a ", "");
\r
863 thisQuery.q_audioTrack1 = "Automatic";
\r
865 if (audioTrack2.Success != false)
\r
867 string[] audioChan = audioTrack2.ToString().Split(',');
\r
868 thisQuery.q_audioTrack2 = audioChan[1];
\r
871 thisQuery.q_audioTrack2 = "None";
\r
874 thisQuery.q_audioTrackMix1 = "Automatic";
\r
875 if (audioTrack1Mix.Success != false)
\r
877 switch (audioTrack1Mix.ToString().Replace("-6 ", "").Replace(" ", ""))
\r
880 thisQuery.q_audioTrackMix1 = "Mono";
\r
883 thisQuery.q_audioTrackMix1 = "Stereo";
\r
886 thisQuery.q_audioTrackMix1 = "Dolby Surround";
\r
889 thisQuery.q_audioTrackMix1 = "Dolby Pro Logic II";
\r
892 thisQuery.q_audioTrackMix1 = "6 Channel Discrete";
\r
895 thisQuery.q_audioTrackMix1 = "Automatic";
\r
900 thisQuery.q_audioTrackMix2 = "Automatic";
\r
901 if (audioTrack2Mix.Success != false)
\r
903 string[] audio2mix = audioTrack2Mix.ToString().Split(',');
\r
904 audio2mix[1] = audio2mix[1].Trim();
\r
905 switch (audio2mix[1])
\r
908 thisQuery.q_audioTrackMix2 = "Mono";
\r
911 thisQuery.q_audioTrackMix2 = "Stereo";
\r
914 thisQuery.q_audioTrackMix2 = "Dolby Surround";
\r
917 thisQuery.q_audioTrackMix2 = "Dolby Pro Logic II";
\r
920 thisQuery.q_audioTrackMix2 = "6 Channel Discrete";
\r
923 thisQuery.q_audioTrackMix2 = "Automatic";
\r
929 if (audioEncoder1.Success != false)
\r
931 audioEncoderConvertion = audioEncoder1.ToString().Replace("-E ", "");
\r
932 switch (audioEncoderConvertion)
\r
935 audioEncoderConvertion = "AAC";
\r
938 audioEncoderConvertion = "MP3";
\r
941 audioEncoderConvertion = "Vorbis";
\r
944 audioEncoderConvertion = "AC3";
\r
947 audioEncoderConvertion = "AAC + AC3";
\r
950 audioEncoderConvertion = "AAC";
\r
953 thisQuery.q_audioEncoder1 = audioEncoderConvertion;
\r
956 if (audioEncoder2.Success != false)
\r
958 audioEncoderConvertion = audioEncoder2.ToString().Replace("-E ", "");
\r
959 string[] audio2enc = audioEncoder2.ToString().Split(',');
\r
960 audio2enc[1] = audio2enc[1].Trim();
\r
961 switch (audio2enc[1])
\r
964 audioEncoderConvertion = "AAC";
\r
967 audioEncoderConvertion = "MP3";
\r
970 audioEncoderConvertion = "Vorbis";
\r
973 audioEncoderConvertion = "AC3";
\r
976 audioEncoderConvertion = "AAC + AC3";
\r
979 audioEncoderConvertion = "AAC";
\r
982 thisQuery.q_audioEncoder2 = audioEncoderConvertion;
\r
987 if (audioBitrate1.Success != false)
\r
988 thisQuery.q_audioBitrate1 = audioBitrate1.ToString().Replace("-B ", "").Trim();
\r
990 thisQuery.q_audioBitrate1 = "";
\r
992 if (audioBitrate2.Success != false)
\r
994 string[] audioBitrateSelect = audioBitrate2.ToString().Split(',');
\r
995 thisQuery.q_audioBitrate2 = audioBitrateSelect[1].Trim();
\r
998 thisQuery.q_audioBitrate2 = "";
\r
1000 // Audio Sample Rate
\r
1001 if (audioSampleRate1.Success != false)
\r
1002 thisQuery.q_audioSamplerate1 = audioSampleRate1.ToString().Replace("-R ", "").Trim();
\r
1004 if (audioSampleRate2.Success != false)
\r
1006 string[] audioSRSelect = audioSampleRate2.ToString().Split(',');
\r
1007 thisQuery.q_audioSamplerate2 = audioSRSelect[1].Trim();
\r
1011 if (subtitles.Success != false)
\r
1012 thisQuery.q_subtitles = subtitles.ToString().Replace("-s ", "");
\r
1015 if (subScan.Success)
\r
1016 thisQuery.q_subtitles = "Autoselect";
\r
1018 thisQuery.q_subtitles = "None";
\r
1021 if (drc.Success != false)
\r
1023 string value = drc.ToString().Replace("-D ", "");
\r
1024 float drcValue = float.Parse(value);
\r
1025 drcValue = drcValue * 10;
\r
1026 thisQuery.q_drc = drcValue;
\r
1029 thisQuery.q_drc = 0;
\r
1031 thisQuery.q_forcedSubs = forcedSubtitles.Success;
\r
1036 //H264 tab and other
\r
1038 #region h264 and other
\r
1042 if (x264.Success != false)
\r
1044 thisQuery.q_h264 = x264.ToString().Replace("-x ", "");
\r
1050 thisQuery.q_verbose = verbose.Success;
\r
1053 catch (Exception exc)
\r
1055 MessageBox.Show("An error has occured in the Query Parser. Please report this error on the forum in the 'Windows' support section. \n\n" + exc.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
\r