public VideoInfo(string videoInput, string videoOutput, int darX, int darY, int creditsStartFrame, int introEndFrame, Zone[] zones) { this.videoInput = videoInput; this.videoOutput = videoOutput; this.creditsStartFrame = creditsStartFrame; this.introEndFrame = introEndFrame; this.zones = zones; }
public static string genCommandline(string input, string output, Dar? d, int hres, int vres, x264Settings xs, Zone[] zones) { int qp; bool display = false; StringBuilder sb = new StringBuilder(); CultureInfo ci = new CultureInfo("en-us"); ///<summary> /// x264 Main Tab Settings ///</summary> // AVC Profiles if (!xs.CustomEncoderOptions.Contains("--profile ")) { switch (xs.Profile) { case 0: sb.Append("--profile baseline "); break; case 1: sb.Append("--profile main "); break; case 2: break; // --profile high is the default value } } // AVC Levels if (!xs.CustomEncoderOptions.Contains("--level ")) if (xs.Level != 15) // unrestricted sb.Append("--level " + AVCLevels.getCLILevelNames()[xs.Level] + " "); // x264 Presets if (!xs.CustomEncoderOptions.Contains("--preset ")) { switch (xs.x264PresetLevel) { case x264Settings.x264PresetLevelModes.ultrafast: sb.Append("--preset ultrafast "); break; case x264Settings.x264PresetLevelModes.superfast: sb.Append("--preset superfast "); break; case x264Settings.x264PresetLevelModes.veryfast: sb.Append("--preset veryfast "); break; case x264Settings.x264PresetLevelModes.faster: sb.Append("--preset faster "); break; case x264Settings.x264PresetLevelModes.fast: sb.Append("--preset fast "); break; //case x264Settings.x264PresetLevelModes.medium: sb.Append("--preset medium "); break; // default value case x264Settings.x264PresetLevelModes.slow: sb.Append("--preset slow "); break; case x264Settings.x264PresetLevelModes.slower: sb.Append("--preset slower "); break; case x264Settings.x264PresetLevelModes.veryslow: sb.Append("--preset veryslow "); break; case x264Settings.x264PresetLevelModes.placebo: sb.Append("--preset placebo "); break; } } // x264 Tunings if (!xs.CustomEncoderOptions.Contains("--tune")) { switch (xs.x264Tuning) { case 1: sb.Append("--tune film "); break; case 2: sb.Append("--tune animation "); break; case 3: sb.Append("--tune grain "); break; case 4: sb.Append("--tune psnr "); break; case 5: sb.Append("--tune ssim "); break; case 6: sb.Append("--tune fastdecode "); break; case 7: sb.Append("--tune touhou "); break; default: break; // default } } // Encoding Modes switch (xs.EncodingMode) { case 0: // ABR if (!xs.CustomEncoderOptions.Contains("--bitrate")) sb.Append("--bitrate " + xs.BitrateQuantizer + " "); break; case 1: // CQ if (!xs.CustomEncoderOptions.Contains("--qp ")) { qp = (int)xs.QuantizerCRF; sb.Append("--qp " + qp.ToString(ci) + " "); } break; case 2: // 2 pass first pass sb.Append("--pass 1 --bitrate " + xs.BitrateQuantizer + " --stats " + "\"" + xs.Logfile + "\" "); break; case 3: // 2 pass second pass case 4: // automated twopass sb.Append("--pass 2 --bitrate " + xs.BitrateQuantizer + " --stats " + "\"" + xs.Logfile + "\" "); break; case 5: // 3 pass first pass sb.Append("--pass 1 --bitrate " + xs.BitrateQuantizer + " --stats " + "\"" + xs.Logfile + "\" "); break; case 6: // 3 pass 2nd pass sb.Append("--pass 3 --bitrate " + xs.BitrateQuantizer + " --stats " + "\"" + xs.Logfile + "\" "); break; case 7: // 3 pass 3rd pass case 8: // automated threepass, show third pass options sb.Append("--pass 3 --bitrate " + xs.BitrateQuantizer + " --stats " + "\"" + xs.Logfile + "\" "); break; case 9: // constant quality if (!xs.CustomEncoderOptions.Contains("--crf")) if (xs.QuantizerCRF != 23) sb.Append("--crf " + xs.QuantizerCRF.ToString(ci) + " "); break; } // Slow 1st Pass if (!xs.CustomEncoderOptions.Contains("--slow-firstpass")) if ((xs.X264SlowFirstpass) && xs.x264PresetLevel < x264Settings.x264PresetLevelModes.placebo && ((xs.EncodingMode == 2) || // 2 pass first pass (xs.EncodingMode == 4) || // automated twopass (xs.EncodingMode == 5) || // 3 pass first pass (xs.EncodingMode == 8))) // automated threepass sb.Append("--slow-firstpass "); // Threads if (!xs.CustomEncoderOptions.Contains("--thread-input")) if (xs.ThreadInput && xs.NbThreads == 1) sb.Append("--thread-input "); if (!xs.CustomEncoderOptions.Contains("--threads")) if (xs.NbThreads > 0) sb.Append("--threads " + xs.NbThreads + " "); ///<summary> /// x264 Frame-Type Tab Settings ///</summary> // H.264 Features if (xs.Deblock) { display = false; switch (xs.x264Tuning) { case 1: case 7: if (xs.AlphaDeblock != -1 || xs.BetaDeblock != -1) display = true; break; case 2: if (xs.AlphaDeblock != 1 || xs.BetaDeblock != 1) display = true; break; case 3: if (xs.AlphaDeblock != -2 || xs.BetaDeblock != -2) display = true; break; default: if (xs.AlphaDeblock != 0 || xs.BetaDeblock != 0) display = true; break; } if (!xs.CustomEncoderOptions.Contains("--deblock ")) if (display) sb.Append("--deblock " + xs.AlphaDeblock + ":" + xs.BetaDeblock + " "); } else { if (!xs.CustomEncoderOptions.Contains("--no-deblock")) if (xs.x264PresetLevel != x264Settings.x264PresetLevelModes.ultrafast || (xs.x264Tuning != 0 && xs.x264Tuning != 6)) sb.Append("--no-deblock "); } if (!xs.CustomEncoderOptions.Contains("--no-cabac")) { if (!xs.Cabac) { if (xs.Profile > 0 && (xs.x264PresetLevel != x264Settings.x264PresetLevelModes.ultrafast || (xs.x264Tuning != 0 && xs.x264Tuning != 6))) sb.Append("--no-cabac "); } } // GOP Size if (!xs.CustomEncoderOptions.Contains("--keyint")) if (xs.KeyframeInterval != 250) // gop size of 250 is default sb.Append("--keyint " + xs.KeyframeInterval + " "); if (!xs.CustomEncoderOptions.Contains("--min-keyint")) if (xs.MinGOPSize != 25) sb.Append("--min-keyint " + xs.MinGOPSize + " "); // B-Frames if (xs.Profile > 0 && !xs.CustomEncoderOptions.Contains("--bframes")) // baseline profile always uses 0 bframes { int iDefaultSettings = 3; switch (xs.x264PresetLevel) { case x264Settings.x264PresetLevelModes.ultrafast: iDefaultSettings = 0; break; case x264Settings.x264PresetLevelModes.veryslow: iDefaultSettings = 8; break; case x264Settings.x264PresetLevelModes.placebo: iDefaultSettings = 16; break; } if (xs.x264Tuning == 2) // animation iDefaultSettings += 2; if (xs.NbBframes != iDefaultSettings) sb.Append("--bframes " + xs.NbBframes + " "); } if (xs.NbBframes > 0) { if (!xs.CustomEncoderOptions.Contains("-b-adapt")) { display = false; if (xs.x264PresetLevel > x264Settings.x264PresetLevelModes.medium) { if (xs.NewAdaptiveBFrames != 2) display = true; } else if (xs.x264PresetLevel > x264Settings.x264PresetLevelModes.ultrafast) { if (xs.NewAdaptiveBFrames != 1) display = true; } else { if (xs.NewAdaptiveBFrames != 0) display = true; } if (display) sb.Append("--b-adapt " + xs.NewAdaptiveBFrames + " "); } if (xs.NbBframes > 1 && !xs.CustomEncoderOptions.Contains("--b-pyramid")) { switch (xs.x264BFramePyramid) // pyramid needs a minimum of 2 b frames { case 1: sb.Append("--b-pyramid strict "); break; case 0: sb.Append("--b-pyramid none "); break; } } if (!xs.CustomEncoderOptions.Contains("--no-weightb")) if (!xs.WeightedBPrediction && xs.x264Tuning != 6 && xs.x264PresetLevel != x264Settings.x264PresetLevelModes.ultrafast) sb.Append("--no-weightb "); } // B-Frames bias if (!xs.CustomEncoderOptions.Contains("--b-bias ")) if (xs.BframeBias != 0.0M) sb.Append("--b-bias " + xs.BframeBias.ToString(ci) + " "); // Other if (!xs.CustomEncoderOptions.Contains("--interlaced")) if (xs.EncodeInterlaced) sb.Append("--interlaced "); if (xs.Scenecut) { if (!xs.CustomEncoderOptions.Contains("--scenecut ")) if ((xs.SCDSensitivity != 40M && xs.x264PresetLevel != x264Settings.x264PresetLevelModes.ultrafast) || (xs.SCDSensitivity != 0M && xs.x264PresetLevel == x264Settings.x264PresetLevelModes.ultrafast)) sb.Append("--scenecut " + xs.SCDSensitivity.ToString(ci) + " "); } else { if (!xs.CustomEncoderOptions.Contains("--no-scenecut")) if (xs.x264PresetLevel != x264Settings.x264PresetLevelModes.ultrafast) sb.Append("--no-scenecut "); } // reference frames if (!xs.CustomEncoderOptions.Contains("--ref ")) { int iDefaultSettings = 0; switch (xs.x264PresetLevel) { case x264Settings.x264PresetLevelModes.ultrafast: case x264Settings.x264PresetLevelModes.superfast: case x264Settings.x264PresetLevelModes.veryfast: iDefaultSettings = 1; break; case x264Settings.x264PresetLevelModes.faster: case x264Settings.x264PresetLevelModes.fast: iDefaultSettings = 2; break; case x264Settings.x264PresetLevelModes.medium: iDefaultSettings = 3; break; case x264Settings.x264PresetLevelModes.slow: iDefaultSettings = 5; break; case x264Settings.x264PresetLevelModes.slower: iDefaultSettings = 8; break; case x264Settings.x264PresetLevelModes.veryslow: case x264Settings.x264PresetLevelModes.placebo: iDefaultSettings = 16; break; } if ((xs.x264Tuning == 2 || xs.x264Tuning == 7) && iDefaultSettings > 1) iDefaultSettings = iDefaultSettings * 2; if (iDefaultSettings != xs.NbRefFrames) sb.Append("--ref " + xs.NbRefFrames + " "); } // WeightedPPrediction if (!xs.CustomEncoderOptions.Contains("--weightp ")) { display = false; switch (xs.x264PresetLevel) { case x264Settings.x264PresetLevelModes.ultrafast: case x264Settings.x264PresetLevelModes.superfast: case x264Settings.x264PresetLevelModes.veryfast: if (xs.WeightedPPrediction != 0) display = true; break; case x264Settings.x264PresetLevelModes.faster: if (xs.WeightedPPrediction != 1) display = true; break; default: if (xs.WeightedPPrediction != 2) display = true; break; } if (xs.x264Tuning == 6 && xs.WeightedPPrediction != 0) display = true; if (xs.Profile == 0) display = false; if (display) sb.Append("--weightp " + xs.WeightedPPrediction + " "); } // Slicing if (!xs.CustomEncoderOptions.Contains("--slices ")) if (xs.SlicesNb != 0) sb.Append("--slices " + xs.SlicesNb + " "); if (!xs.CustomEncoderOptions.Contains("--slice-max-size ")) if (xs.MaxSliceSyzeBytes != 0) sb.Append("--slice-max-size " + xs.MaxSliceSyzeBytes + " "); if (!xs.CustomEncoderOptions.Contains("--slice-max-mbs ")) if (xs.MaxSliceSyzeMBs != 0) sb.Append("--slice-max-mbs " + xs.MaxSliceSyzeMBs + " "); ///<summary> /// x264 Rate Control Tab Settings /// </summary> if (!xs.CustomEncoderOptions.Contains("--qpmin ")) if (xs.MinQuantizer != 10) sb.Append("--qpmin " + xs.MinQuantizer + " "); if (!xs.CustomEncoderOptions.Contains("--qpmax ")) if (xs.MaxQuantizer != 51) sb.Append("--qpmax " + xs.MaxQuantizer + " "); if (!xs.CustomEncoderOptions.Contains("--qpstep ")) if (xs.MaxQuantDelta != 4) sb.Append("--qpstep " + xs.MaxQuantDelta + " "); if (xs.IPFactor != 1.4M) { display = true; if (xs.x264Tuning == 3 && xs.IPFactor == 1.1M) display = false; if (!xs.CustomEncoderOptions.Contains("--ipratio ")) if (display) sb.Append("--ipratio " + xs.IPFactor.ToString(ci) + " "); } if (xs.PBFactor != 1.3M) { display = true; if (xs.x264Tuning == 3 && xs.PBFactor == 1.1M) display = false; if (!xs.CustomEncoderOptions.Contains("--pbratio ")) if (display) sb.Append("--pbratio " + xs.PBFactor.ToString(ci) + " "); } if (!xs.CustomEncoderOptions.Contains("--chroma-qp-offset ")) if (xs.ChromaQPOffset != 0.0M) sb.Append("--chroma-qp-offset " + xs.ChromaQPOffset.ToString(ci) + " "); if (xs.EncodingMode != 1) // doesn't apply to CQ mode { if (!xs.CustomEncoderOptions.Contains("--vbv-bufsize ")) if (xs.VBVBufferSize > 0) sb.Append("--vbv-bufsize " + xs.VBVBufferSize + " "); if (!xs.CustomEncoderOptions.Contains("--vbv-maxrate ")) if (xs.VBVMaxBitrate > 0) sb.Append("--vbv-maxrate " + xs.VBVMaxBitrate + " "); if (!xs.CustomEncoderOptions.Contains("--vbv-init ")) if (xs.VBVInitialBuffer != 0.9M) sb.Append("--vbv-init " + xs.VBVInitialBuffer.ToString(ci) + " "); if (!xs.CustomEncoderOptions.Contains("--ratetol ")) if (xs.BitrateVariance != 1.0M) sb.Append("--ratetol " + xs.BitrateVariance.ToString(ci) + " "); if (!xs.CustomEncoderOptions.Contains("--qcomp ")) { display = true; if ((xs.x264Tuning == 3 && xs.QuantCompression == 0.8M) || (xs.x264Tuning != 3 && xs.QuantCompression == 0.6M)) display = false; if (display) sb.Append("--qcomp " + xs.QuantCompression.ToString(ci) + " "); } if (xs.EncodingMode > 1) // applies only to twopass { if (!xs.CustomEncoderOptions.Contains("--cplxblur ")) if (xs.TempComplexityBlur != 20) sb.Append("--cplxblur " + xs.TempComplexityBlur.ToString(ci) + " "); if (!xs.CustomEncoderOptions.Contains("--qblur ")) if (xs.TempQuanBlurCC != 0.5M) sb.Append("--qblur " + xs.TempQuanBlurCC.ToString(ci) + " "); } } // Dead Zones if (!xs.CustomEncoderOptions.Contains("--deadzone-inter ")) { display = true; if ((xs.x264Tuning != 3 && xs.DeadZoneInter == 21) || (xs.x264Tuning == 3 && xs.DeadZoneInter == 6)) display = false; if (display) sb.Append("--deadzone-inter " + xs.DeadZoneInter + " "); } if (!xs.CustomEncoderOptions.Contains("--deadzone-intra ")) { display = true; if ((xs.x264Tuning != 3 && xs.DeadZoneIntra == 11) || (xs.x264Tuning == 3 && xs.DeadZoneIntra == 6)) display = false; if (display) sb.Append("--deadzone-intra " + xs.DeadZoneIntra + " "); } // Disable Macroblok Tree if (!xs.NoMBTree) { if (!xs.CustomEncoderOptions.Contains("--no-mbtree")) if (xs.x264PresetLevel > x264Settings.x264PresetLevelModes.veryfast) sb.Append("--no-mbtree "); } else { // RC Lookahead if (!xs.CustomEncoderOptions.Contains("--rc-lookahead ")) { display = false; switch (xs.x264PresetLevel) { case x264Settings.x264PresetLevelModes.faster: if (xs.Lookahead != 20) display = true; break; case x264Settings.x264PresetLevelModes.fast: if (xs.Lookahead != 30) display = true; break; case x264Settings.x264PresetLevelModes.medium: if (xs.Lookahead != 40) display = true; break; case x264Settings.x264PresetLevelModes.slow: if (xs.Lookahead != 50) display = true; break; case x264Settings.x264PresetLevelModes.slower: case x264Settings.x264PresetLevelModes.veryslow: case x264Settings.x264PresetLevelModes.placebo: if (xs.Lookahead != 60) display = true; break; } if (display) sb.Append("--rc-lookahead " + xs.Lookahead + " "); } } // AQ-Mode if (xs.EncodingMode != (int)VideoCodecSettings.Mode.CQ) { if (xs.AQmode > 0) { if (!xs.CustomEncoderOptions.Contains("--aq-mode ")) { display = true; if ((xs.x264Tuning != 5 && xs.AQmode == 1) || (xs.x264Tuning == 5 && xs.AQmode == 2)) display = false; if (display) sb.Append("--aq-mode " + xs.AQmode.ToString() + " "); } display = false; switch (xs.x264Tuning) { case 2: if (xs.AQstrength != 0.6M) display = true; break; case 3: if (xs.AQstrength != 0.5M) display = true; break; case 7: if (xs.AQstrength != 1.3M) display = true; break; default: if (xs.AQstrength != 1.0M) display = true; break; } if (!xs.CustomEncoderOptions.Contains("--aq-strength ")) if (display) sb.Append("--aq-strength " + xs.AQstrength.ToString(ci) + " "); } else { if (!xs.CustomEncoderOptions.Contains("--aq-mode ")) if (xs.x264PresetLevel != x264Settings.x264PresetLevelModes.ultrafast && xs.x264Tuning != 4) sb.Append("--aq-mode 0 "); } } // custom matrices if (xs.QuantizerMatrixType > 0) { switch (xs.QuantizerMatrixType) { case 1: if (!xs.CustomEncoderOptions.Contains("--cqm ")) sb.Append("--cqm \"jvt\" "); break; case 2: if (!xs.CustomEncoderOptions.Contains("--cqmfile")) sb.Append("--cqmfile \"" + xs.QuantizerMatrix + "\" "); break; } } ///<summary> /// x264 Analysis Tab Settings /// </summary> // Disable Chroma Motion Estimation if (!xs.CustomEncoderOptions.Contains("--no-chroma-me")) if (!xs.ChromaME) sb.Append("--no-chroma-me "); // Motion Estimation Range if (!xs.CustomEncoderOptions.Contains("--merange ")) { if ((xs.x264PresetLevel <= x264Settings.x264PresetLevelModes.slower && xs.MERange != 16) || (xs.x264PresetLevel >= x264Settings.x264PresetLevelModes.veryslow && xs.MERange != 24)) sb.Append("--merange " + xs.MERange + " "); } // ME Type if (!xs.CustomEncoderOptions.Contains("--me ")) { display = false; switch (xs.x264PresetLevel) { case x264Settings.x264PresetLevelModes.ultrafast: case x264Settings.x264PresetLevelModes.superfast: if (xs.METype != 0) display = true; break; case x264Settings.x264PresetLevelModes.veryfast: case x264Settings.x264PresetLevelModes.faster: case x264Settings.x264PresetLevelModes.fast: case x264Settings.x264PresetLevelModes.medium: if (xs.METype != 1) display = true; break; case x264Settings.x264PresetLevelModes.slow: case x264Settings.x264PresetLevelModes.slower: case x264Settings.x264PresetLevelModes.veryslow: if (xs.METype != 2) display = true; break; case x264Settings.x264PresetLevelModes.placebo: if (xs.METype != 4) display = true; break; } if (display) { switch (xs.METype) { case 0: sb.Append("--me dia "); break; case 1: sb.Append("--me hex "); break; case 2: sb.Append("--me umh "); break; case 3: sb.Append("--me esa "); break; case 4: sb.Append("--me tesa "); break; } } } if (!xs.CustomEncoderOptions.Contains("--direct ")) { display = false; if (xs.x264PresetLevel > x264Settings.x264PresetLevelModes.medium) { if (xs.BframePredictionMode != 3) display = true; } else if (xs.BframePredictionMode != 1) display = true; if (display) { switch (xs.BframePredictionMode) { case 0: sb.Append("--direct none "); break; case 1: sb.Append("--direct spatial "); break; case 2: sb.Append("--direct temporal "); break; case 3: sb.Append("--direct auto "); break; } } } if (!xs.CustomEncoderOptions.Contains("--nr ")) if (xs.NoiseReduction > 0) sb.Append("--nr " + xs.NoiseReduction + " "); // subpel refinement if (!xs.CustomEncoderOptions.Contains("--subme ")) { display = false; switch (xs.x264PresetLevel) { case x264Settings.x264PresetLevelModes.ultrafast: if (xs.SubPelRefinement != 0) display = true; break; case x264Settings.x264PresetLevelModes.superfast: if (xs.SubPelRefinement != 1) display = true; break; case x264Settings.x264PresetLevelModes.veryfast: if (xs.SubPelRefinement != 2) display = true; break; case x264Settings.x264PresetLevelModes.faster: if (xs.SubPelRefinement != 4) display = true; break; case x264Settings.x264PresetLevelModes.fast: if (xs.SubPelRefinement != 6) display = true; break; case x264Settings.x264PresetLevelModes.medium: if (xs.SubPelRefinement != 7) display = true; break; case x264Settings.x264PresetLevelModes.slow: if (xs.SubPelRefinement != 8) display = true; break; case x264Settings.x264PresetLevelModes.slower: if (xs.SubPelRefinement != 9) display = true; break; case x264Settings.x264PresetLevelModes.veryslow: if (xs.SubPelRefinement != 10) display = true; break; case x264Settings.x264PresetLevelModes.placebo: if (xs.SubPelRefinement != 10) display = true; break; } if (display) sb.Append("--subme " + (xs.SubPelRefinement) + " "); } // macroblock types if (!xs.CustomEncoderOptions.Contains("--partitions ")) { bool bExpectedP8x8mv = true; bool bExpectedB8x8mv = true; bool bExpectedI4x4mv = true; bool bExpectedI8x8mv = true; bool bExpectedP4x4mv = true; switch (xs.x264PresetLevel) { case x264Settings.x264PresetLevelModes.ultrafast: bExpectedP8x8mv = false; bExpectedB8x8mv = false; bExpectedI4x4mv = false; bExpectedI8x8mv = false; bExpectedP4x4mv = false; break; case x264Settings.x264PresetLevelModes.superfast: bExpectedP8x8mv = false; bExpectedB8x8mv = false; bExpectedP4x4mv = false; break; case x264Settings.x264PresetLevelModes.veryfast: case x264Settings.x264PresetLevelModes.faster: case x264Settings.x264PresetLevelModes.fast: case x264Settings.x264PresetLevelModes.medium: case x264Settings.x264PresetLevelModes.slow: bExpectedP4x4mv = false; break; } if (xs.x264Tuning == 7 && bExpectedP8x8mv) bExpectedP4x4mv = true; if (bExpectedP8x8mv != xs.P8x8mv || bExpectedB8x8mv != xs.B8x8mv || bExpectedI4x4mv != xs.I4x4mv || bExpectedI8x8mv != xs.I8x8mv || bExpectedP4x4mv != xs.P4x4mv) { if (xs.P8x8mv || xs.B8x8mv || xs.I4x4mv || xs.I8x8mv || xs.P4x4mv) { sb.Append("--partitions "); if (xs.I4x4mv && xs.I8x8mv && xs.P4x4mv && xs.P8x8mv && xs.B8x8mv) sb.Append("all "); else { if (xs.P8x8mv) // default is checked sb.Append("p8x8,"); if (xs.B8x8mv) // default is checked sb.Append("b8x8,"); if (xs.I4x4mv) // default is checked sb.Append("i4x4,"); if (xs.P4x4mv) // default is unchecked sb.Append("p4x4,"); if (xs.I8x8mv) // default is checked sb.Append("i8x8"); if (sb.ToString().EndsWith(",")) sb.Remove(sb.Length - 1, 1); } if (!sb.ToString().EndsWith(" ")) sb.Append(" "); } else sb.Append("--partitions none "); } } if (!xs.CustomEncoderOptions.Contains("--no-8x8dct")) if (!xs.AdaptiveDCT) if (xs.Profile > 0 && xs.x264PresetLevel > x264Settings.x264PresetLevelModes.ultrafast) sb.Append("--no-8x8dct "); // Trellis if (!xs.CustomEncoderOptions.Contains("--trellis ") && xs.Cabac) { display = false; switch (xs.x264PresetLevel) { case x264Settings.x264PresetLevelModes.ultrafast: case x264Settings.x264PresetLevelModes.superfast: case x264Settings.x264PresetLevelModes.veryfast: if (xs.X264Trellis != 0) display = true; break; case x264Settings.x264PresetLevelModes.faster: case x264Settings.x264PresetLevelModes.fast: case x264Settings.x264PresetLevelModes.medium: case x264Settings.x264PresetLevelModes.slow: if (xs.X264Trellis != 1) display = true; break; case x264Settings.x264PresetLevelModes.slower: case x264Settings.x264PresetLevelModes.veryslow: case x264Settings.x264PresetLevelModes.placebo: if (xs.X264Trellis != 2) display = true; break; } if (display) sb.Append("--trellis " + xs.X264Trellis + " "); } if (!xs.CustomEncoderOptions.Contains("--psy-rd ")) { if (xs.SubPelRefinement > 5) { display = false; switch (xs.x264Tuning) { case 1: if ((xs.PsyRDO != 1.0M) && (xs.PsyTrellis != 0.15M)) display = true; break; case 2: if ((xs.PsyRDO != 0.4M) && (xs.PsyTrellis != 0.0M)) display = true; break; case 3: if ((xs.PsyRDO != 1.0M) && (xs.PsyTrellis != 0.25M)) display = true; break; case 7: if ((xs.PsyRDO != 1.0M) && (xs.PsyTrellis != 0.2M)) display = true; break; default: if ((xs.PsyRDO != 1.0M) || (xs.PsyTrellis != 0.0M)) display = true; break; } if (display) sb.Append("--psy-rd " + xs.PsyRDO.ToString(ci) + ":" + xs.PsyTrellis.ToString(ci) + " "); } } else { display = false; switch (xs.x264Tuning) { case 1: if (xs.PsyTrellis != 0.15M) display = true; break; case 3: if (xs.PsyTrellis != 0.25M) display = true; break; case 7: if (xs.PsyTrellis != 0.2M) display = true; break; case 0: case 4: { if (xs.PsyTrellis != 0.0M) display = true; } break; } if (!xs.CustomEncoderOptions.Contains("--psy-rd 0: ")) if (display) sb.Append("--psy-rd 0:" + xs.PsyTrellis.ToString(ci) + " "); } if (!xs.CustomEncoderOptions.Contains("--no-mixed-refs")) if (xs.NoMixedRefs) if (xs.x264PresetLevel >= x264Settings.x264PresetLevelModes.fast) sb.Append("--no-mixed-refs "); if (!xs.CustomEncoderOptions.Contains("--no-dct-decimate")) if (xs.NoDCTDecimate) if (xs.x264Tuning != 3) sb.Append("--no-dct-decimate "); if (!xs.CustomEncoderOptions.Contains("--no-fast-pskip")) if (xs.NoFastPSkip) if (xs.x264PresetLevel != x264Settings.x264PresetLevelModes.placebo) sb.Append("--no-fast-pskip "); if (!xs.CustomEncoderOptions.Contains("--no-psy")) if (xs.NoPsy && (xs.x264Tuning != 4 && xs.x264Tuning != 5)) sb.Append("--no-psy "); if (!xs.CustomEncoderOptions.Contains("--aud")) if (xs.X264Aud) sb.Append("--aud "); if (!xs.CustomEncoderOptions.Contains("--nal-hrd")) if (xs.X264Nalhrd) sb.Append("--nal-hrd vbr "); ///<summary> /// x264 Misc Tab Settings /// </summary> // QPFile if (!xs.CustomEncoderOptions.Contains("-qpfile ")) if (xs.UseQPFile) if (xs.EncodingMode == 0 || xs.EncodingMode == 1 || xs.EncodingMode == 2 || xs.EncodingMode == 5 || xs.EncodingMode == 9) sb.Append("--qpfile " + "\"" + xs.QPFile + "\" "); if (!xs.CustomEncoderOptions.Contains("--psnr")) if (xs.PSNRCalculation) sb.Append("--psnr "); if (!xs.CustomEncoderOptions.Contains("--ssim")) if (xs.SSIMCalculation) sb.Append("--ssim "); if (!xs.CustomEncoderOptions.Contains("--fullrange on")) if (xs.fullRange) sb.Append("--fullrange on "); if (!xs.CustomEncoderOptions.Equals("")) // add custom encoder options sb.Append(xs.CustomEncoderOptions + " "); if (zones != null && zones.Length > 0 && xs.CreditsQuantizer >= 1.0M) { sb.Append("--zones "); foreach (Zone zone in zones) { sb.Append(zone.startFrame + "," + zone.endFrame + ","); if (zone.mode == ZONEMODE.Quantizer) { sb.Append("q="); sb.Append(zone.modifier + "/"); } if (zone.mode == ZONEMODE.Weight) { sb.Append("b="); double mod = (double)zone.modifier / 100.0; sb.Append(mod.ToString(ci) + "/"); } } sb.Remove(sb.Length - 1, 1); sb.Append(" "); } if (!xs.CustomEncoderOptions.Contains("--sar ")) { if (d.HasValue) { Sar s = d.Value.ToSar(hres, vres); sb.Append("--sar " + s.X + ":" + s.Y + " "); } } //add the rest of the commandline regarding the output if (xs.EncodingMode == 2 || xs.EncodingMode == 5) sb.Append("--output NUL "); else sb.Append("--output " + "\"" + output + "\" "); sb.Append("\"" + input + "\" "); return sb.ToString(); }
/// <summary> /// shows the zones given as argument in the GUI /// first clears the listview of any items, then add one item after the other /// </summary> /// <param name="zones">the zones to be displayed</param> private void showZones(Zone[] zones) { this.zoneListView.Items.Clear(); foreach (Zone z in zones) { ListViewItem item = new ListViewItem(new string[] { z.startFrame.ToString(), z.endFrame.ToString(), z.mode.ToString(), z.modifier.ToString() }); item.Tag = z; zoneListView.Items.Add(item); } }
private void removeZoneButton_Click(object sender, System.EventArgs e) { if (this.zoneListView.SelectedItems.Count > 0) { foreach (ListViewItem item in zoneListView.SelectedItems) { zoneListView.Items.Remove(item); } Zone[] newZones = new Zone[zoneListView.Items.Count]; int index = 0; foreach (ListViewItem item in zoneListView.Items) { Zone z = (Zone)item.Tag; newZones[index] = z; index++; } zones = newZones; showZones(zones); updateGUI(); } }
private void addZoneButton_Click(object sender, System.EventArgs e) { if (startFrame.Text.Equals("") || endFrame.Text.Equals("")) MessageBox.Show("You must specify both start and end frame", "Missing input", MessageBoxButtons.OK, MessageBoxIcon.Stop); else { Zone zone = new Zone(); zone.startFrame = Int32.Parse(startFrame.Text); zone.endFrame = Int32.Parse(endFrame.Text); if (zone.endFrame <= zone.startFrame) { MessageBox.Show("The end frame must be larger than the start frame", "Invalid zone configuration", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } if (zoneMode.SelectedIndex == 0) zone.mode = ZONEMODE.Quantizer; else zone.mode = ZONEMODE.Weight; zone.modifier = zoneModifier.Value; Zone[] newZones = new Zone[zones.Length + 1]; int index = 0; if (zones.Length == 0) // no zones defined yet newZones[0] = zone; bool iterationAborted = false, zoneInserted = false; foreach (Zone z in zones) { if (zone.startFrame > z.endFrame) // new zone starts after the current one { newZones[index] = z; } else if (zone.endFrame < z.startFrame) // new zone end before the current one { if (!zoneInserted) { newZones[index] = zone; zoneInserted = true; index++; } newZones[index] = z; } else if (z.endFrame >= zone.startFrame || (z.startFrame <= zone.endFrame && z.endFrame >= zone.endFrame)) // intersection { string errorMessage = "The new zone intersects with an existing zone:\nstart:" + z.startFrame + " end: " + z.endFrame; MessageBox.Show(errorMessage, "Invalid zone configuration", MessageBoxButtons.OK, MessageBoxIcon.Stop); iterationAborted = true; break; } index++; } if (!zoneInserted) // in this case the new zone comes after all the others newZones[index] = zone; if (!iterationAborted) { zones = newZones; this.showZones(zones); } updateGUI(); } }
public static string genSnowCommandline(string input, string output, snowSettings ss, Zone[] zones) { StringBuilder sb = new StringBuilder(); CultureInfo ci = new CultureInfo("en-us"); sb.Append("\"" + input + "\" -ovc lavc -nosound "); switch (ss.EncodingMode) { case 0: // CBR sb.Append("-lavcopts vcodec=snow:vbitrate=" + ss.BitrateQuantizer + ":"); // add bitrate break; case 1: // CQ sb.Append("-lavcopts vcodec=snow:vqscale=" + ss.Quantizer + ":"); break; case 2: // 2 pass first pass sb.Append("-o NUL: -passlogfile " + "\"" + ss.Logfile + "\" "); // add logfile sb.Append("-lavcopts vcodec=snow:vpass=1:vqscale=5:"); // workaround for corrupted first passes break; case 3: // 2 pass second pass case 4: // automated twopass sb.Append(" -passlogfile " + "\"" + ss.Logfile + "\" "); // add logfile sb.Append("-lavcopts vcodec=snow:vpass=2:vbitrate=" + ss.BitrateQuantizer + ":"); // add pass & bitrate break; case 5: sb.Append("-o NUL: -passlogfile " + "\"" + ss.Logfile + "\" "); // add logfile sb.Append("-lavcopts vcodec=snow:vpass=1:vqscale=5:"); // workaround for corrupted first passes break; case 6: sb.Append(" -passlogfile " + "\"" + ss.Logfile + "\" "); // add logfile sb.Append("-lavcopts vcodec=snow:vpass=3:vbitrate=" + ss.BitrateQuantizer + ":"); // add pass & bitrate break; case 7: sb.Append(" -passlogfile " + "\"" + ss.Logfile + "\" "); // add logfile sb.Append("-lavcopts vcodec=snow:vpass=3:vbitrate=" + ss.BitrateQuantizer + ":"); // add pass & bitrate break; } if (ss.PredictionMode != 0) sb.Append("pred=" + ss.PredictionMode + ":"); switch (ss.MECompFullpel) { case 0: break; case 1: sb.Append("cmp=1:"); break; case 2: sb.Append("cmp=11:"); break; case 3: sb.Append("cmp=12:"); break; } switch (ss.MECompHpel) { case 0: break; case 1: sb.Append("subcmp=1:"); break; case 2: sb.Append("subcmp=11:"); break; case 3: sb.Append("subcmp=12:"); break; } switch (ss.MBComp) { case 0: break; case 1: sb.Append("mbcmp=1:"); break; case 2: sb.Append("mbcmp=11:"); break; case 3: sb.Append("mbcmp=12:"); break; } if (ss.QPel) // default is unchecked sb.Append("qpel:"); if (ss.V4MV) // default is unchecked sb.Append("v4mv:"); if (ss.NbMotionPredictors != 0) sb.Append("last_pred=" + ss.NbMotionPredictors.ToString(ci) + ":"); sb.Append("vstrict=-2:"); if (zones != null && zones.Length > 0 && ss.CreditsQuantizer >= new decimal(1)) { sb.Append("-vrc_override="); foreach (Zone zone in zones) { if (zone.mode == ZONEMODE.Quantizer) sb.Append(zone.startFrame + "," + zone.endFrame + "," + zone.modifier + "/"); else sb.Append(zone.startFrame + "," + zone.endFrame + ",-" + zone.modifier + "/"); } sb.Remove(sb.Length - 1, 1); // remove trailing /(zone separator) sb.Append(":"); } if (sb.ToString().EndsWith(":")) // remove the last : sb.Remove(sb.Length - 1, 1); if (ss.EncodingMode != 2) { sb.Append(" -o \"" + output + "\" -of "); // rest of mencoder options int outputType = getVideoOutputType(output); if (outputType == 0) // AVI sb.Append("avi -ffourcc " + ss.FourCCs[ss.FourCC] + " "); if (outputType >= 1) // RAW sb.Append("rawvideo "); } return sb.ToString(); }
/// <summary> /// takes a series of non overlapping zones and adds zones with weight 1.0 in between /// this is used for xvid which doesn't know zone end frames /// </summary> /// <param name="zones">a set of zones to be analyzed</param> /// <param name="nbOfFrames">number of frames the video source has</param> /// <returns>an array of all the zones</returns> public static Zone[] createHelperZones(Zone[] zones, int nbOfFrames) { ArrayList newZones = new ArrayList(); Zone z = zones[0]; Zone newZone = new Zone(); newZone.mode = ZONEMODE.Weight; newZone.modifier = (decimal)100; if (z.startFrame > 0) // zone doesn't start at the beginning, add zone before the first configured zone { newZone.startFrame = 0; newZone.endFrame = z.startFrame - 1; newZones.Add(newZone); } if (zones.Length == 1) // special case { newZones.Add(z); if (z.endFrame < nbOfFrames - 1) // we hav to add an end zone { newZone.startFrame = z.endFrame + 1; newZone.endFrame = nbOfFrames - 1; newZones.Add(newZone); } } else if (zones.Length == 2) { newZones.Add(z); Zone second = zones[1]; if (z.endFrame + 1 < second.startFrame) // new zone needs to go in between { newZone.startFrame = z.endFrame + 1; newZone.endFrame = second.startFrame - 1; newZones.Add(newZone); } newZones.Add(second); if (second.endFrame < nbOfFrames - 1) // add end zone { newZone.startFrame = second.endFrame + 1; newZone.endFrame = nbOfFrames - 1; newZones.Add(newZone); } } else { for (int i = 0; i <= zones.Length - 2; i++) { Zone first = zones[i]; Zone second = zones[i + 1]; if (first.endFrame + 1 == second.startFrame) // zones are adjacent { newZones.Add(first); continue; } else // zones are not adjacent, create filler zone { newZone.startFrame = first.endFrame + 1; newZone.endFrame = second.startFrame - 1; newZones.Add(first); newZones.Add(newZone); } } z = zones[zones.Length - 1]; newZones.Add(z); if (z.endFrame != nbOfFrames - 1) // we have to add another zone extending till the end of the video { newZone.startFrame = z.endFrame + 1; newZone.endFrame = nbOfFrames - 1; newZones.Add(newZone); } } Zone[] retval = new Zone[newZones.Count]; int index = 0; foreach (object o in newZones) { z = (Zone)o; if (index < 64) { retval[index] = z; index++; } else { DialogResult dr = MessageBox.Show("XviD only supports 64 zones. Including filler zones your current\r\nconfiguration yields " + retval.Length + " zones. Do you want to discard the " + "remaining zones?\r\nPress Cancel to reconfigure your zones. Keep in mind that if you have no adjacent zones, a filler zone will have to be added\r\nso 32 non adjacent zones is the " + "maximum number of zones you can have. Both intro and credits region also require a zone.", "Too many zones", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning); if (dr == DialogResult.OK) { break; } else // user wants to abort { return(null); } } } return(retval); }
/// <summary> /// compiles the final zone configuration based on intro end frame, credits start frame and the configured zones /// </summary> /// <param name="vSettings">the video settings containing the list of configured zones</param> /// <param name="introEndFrame">the frame where the intro ends</param> /// <param name="creditsStartFrame">the frame where the credits begin</param> /// <param name="zones">the zones that are returned</param> /// <param name="frameCount">total number of frames in the video</param> /// <returns>an array of zones objects in the proper order</returns> public static bool GetFinalZoneConfiguration(VideoCodecSettings vSettings, int introEndFrame, int creditsStartFrame, ref Zone[] zones, int frameCount) { Zone introZone = new Zone(); Zone creditsZone = new Zone(); bool doIntroZone = false, doCreditsZone = false; int flushZonesStart = 0, flushZonesEnd = 0; if (introEndFrame > 0) // add the intro zone { introZone.startFrame = 0; introZone.endFrame = introEndFrame; introZone.mode = ZONEMODE.Quantizer; introZone.modifier = vSettings.CreditsQuantizer; if (zones.Length > 0) { Zone z = zones[0]; if (z.startFrame > introZone.endFrame) // the first configured zone starts after the intro zone { doIntroZone = true; } else { flushZonesStart = 1; int numberOfConfiguredZones = zones.Length; while (flushZonesStart <= numberOfConfiguredZones) // iterate through all zones backwards until we find the first that goes with the intro { Zone conflict = zones[flushZonesStart]; if (conflict.startFrame <= introZone.endFrame) // zone starts before the end of the intro -> conflict { flushZonesStart++; } else { break; } } DialogResult dr = MessageBox.Show("Your intro zone overlaps " + flushZonesStart + " zone(s) configured\nin the codec settings.\n" + "Do you want to remove those zones and add the intro zone instead?", "Zone overlap detected", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning); if (dr == DialogResult.Yes) { doIntroZone = true; } else if (dr == DialogResult.Cancel) // abort { return(false); } else // discard the intro zone { flushZonesStart = 0; } } } else { doIntroZone = true; } } if (creditsStartFrame > 0) // add the credits zone { creditsZone.startFrame = creditsStartFrame; creditsZone.endFrame = frameCount - 1; creditsZone.mode = ZONEMODE.Quantizer; creditsZone.modifier = vSettings.CreditsQuantizer; if (zones.Length > 0) { Zone z = zones[zones.Length - 1]; // get the last zone if (z.endFrame < creditsZone.startFrame) // the last configured zone ends before the credits start zone { doCreditsZone = true; } else { flushZonesEnd = 1; int numberOfConfiguredZones = zones.Length; while (numberOfConfiguredZones - flushZonesEnd - 1 >= 0) // iterate through all zones backwards until we find the first that goes with the credits { Zone conflict = zones[numberOfConfiguredZones - flushZonesEnd - 1]; if (conflict.endFrame >= creditsZone.startFrame) // zone ends after the end of the credits -> conflict { flushZonesEnd++; } else { break; } } DialogResult dr = MessageBox.Show("Your credits zone overlaps " + flushZonesEnd + " zone(s) configured\nin the codec settings.\n" + "Do you want to remove those zones and add the credits zone instead?", "Zone overlap detected", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning); if (dr == DialogResult.Yes) { doCreditsZone = true; } else if (dr == DialogResult.Cancel) // abort { return(false); } else // discard the credits zone { flushZonesEnd = 0; } } } else // no additional zones configured { doCreditsZone = true; } } int newZoneSize = zones.Length - flushZonesStart - flushZonesEnd; if (doIntroZone) { newZoneSize++; } if (doCreditsZone) { newZoneSize++; } Zone[] newZones = new Zone[newZoneSize]; int index = 0; if (doIntroZone) { newZones[index] = introZone; index++; } for (int i = flushZonesStart; i < zones.Length - flushZonesEnd; i++) { newZones[index] = zones[i]; index++; } if (doCreditsZone) { newZones[index] = creditsZone; index++; } if (vSettings is xvidSettings && newZones.Length > 0) { Zone[] xvidZones = createHelperZones(newZones, frameCount); if (xvidZones == null) { return(false); } else { zones = xvidZones; return(true); } } zones = newZones; return(true); }
/// <summary> /// at first, the job from the currently configured settings is generated. In addition, we find out if this job is /// a part of an automated series of jobs. If so, it means the first generated job was the second pass, and we have /// to create the first pass using the same settings /// then, all the generated jobs are returned /// </summary> /// <returns>an Array of VideoJobs in the order they are to be encoded</returns> public JobChain prepareVideoJob(string movieInput, string movieOutput, VideoCodecSettings settings, Dar? dar, bool prerender, bool checkVideo, Zone[] zones) { bool twoPasses = false, threePasses = false; if (settings.EncodingMode == 4) // automated twopass twoPasses = true; else if (settings.EncodingMode == 8) // automated threepass threePasses = true; VideoJob prerenderJob = null; string hfyuFile = null; string inputAVS = movieInput; if (prerender) { hfyuFile = Path.Combine(Path.GetDirectoryName(movieInput), "hfyu_" + Path.GetFileNameWithoutExtension(movieInput) + ".avi"); inputAVS = Path.ChangeExtension(hfyuFile, ".avs"); if (File.Exists(hfyuFile)) { if (MessageBox.Show("The intended temporary file, " + hfyuFile + " already exists.\r\n" + "Do you wish to over-write it?", "File already exists", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No) return null; } if (File.Exists(inputAVS)) { if (MessageBox.Show("The intended temporary file, " + inputAVS + " already exists.\r\n" + "Do you wish to over-write it?", "File already exists", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No) return null; } try { StreamWriter hfyuWrapper = new StreamWriter(inputAVS, false, Encoding.Default); hfyuWrapper.WriteLine("AviSource(\"" + hfyuFile + "\")"); hfyuWrapper.Close(); } catch (IOException) { return null; } prerenderJob = this.generateVideoJob(movieInput, hfyuFile, new hfyuSettings(), dar, zones); if (prerenderJob == null) return null; } if (checkVideo) { VideoUtil vUtil = new VideoUtil(mainForm); string error = vUtil.checkVideo(movieInput); if (error != null) { bool bContinue = mainForm.DialogManager.createJobs(error); if (!bContinue) { MessageBox.Show("Job creation aborted due to invalid AviSynth script"); return null; } } } VideoJob job = this.generateVideoJob(inputAVS, movieOutput, settings, prerender, dar, zones); VideoJob firstpass = null; VideoJob middlepass = null; if (job != null) { if (twoPasses || threePasses) // we just created the last pass, now create previous one(s) { job.FilesToDelete.Add(job.Settings.Logfile); if (job.Settings.SettingsID.Equals("x264")) job.FilesToDelete.Add(mbtreeFile); firstpass = cloneJob(job); firstpass.Output = ""; // the first pass has no output firstpass.Settings.EncodingMode = 2; firstpass.DAR = dar; if (threePasses) { firstpass.Settings.EncodingMode = 5; // change to 3 pass 3rd pass just for show middlepass = cloneJob(job); middlepass.Settings.EncodingMode = 6; // 3 pass 2nd pass if (mainForm.Settings.Keep2of3passOutput) // give the 2nd pass a new name { middlepass.Output = Path.Combine(Path.GetDirectoryName(job.Output), Path.GetFileNameWithoutExtension(job.Output) + "-2ndpass" + Path.GetExtension(job.Output)); job.FilesToDelete.Add(middlepass.Output); } middlepass.DAR = dar; } } if (prerender) { job.FilesToDelete.Add(hfyuFile); job.FilesToDelete.Add(inputAVS); } List<VideoJob> jobList = new List<VideoJob>(); if (prerenderJob != null) jobList.Add(prerenderJob); if (firstpass != null) jobList.Add(firstpass); if (middlepass != null) // we have a middle pass jobList.Add(middlepass); jobList.Add(job); return new SequentialChain(jobList.ToArray()); } return null; }
public static string genCommandline(string input, string output, Dar? d, xvidSettings xs, int hres, int vres, Zone[] zones) { StringBuilder sb = new StringBuilder(); CultureInfo ci = new CultureInfo("en-us"); sb.Append("-i \"" + input + "\" "); switch (xs.EncodingMode) { case 0: // CBR sb.Append("-single -bitrate " + xs.BitrateQuantizer + " "); // add bitrate break; case 1: // CQ sb.Append("-single -cq " + xs.Quantizer.ToString(ci) + " "); // add quantizer break; case 2: // 2 pass first pass sb.Append("-pass1 " + "\"" + xs.Logfile + "\" -bitrate " + xs.BitrateQuantizer + " "); // add logfile break; case 3: // 2 pass second pass case 4: // automated twopass sb.Append("-pass2 " + "\"" + xs.Logfile + "\" -bitrate " + xs.BitrateQuantizer + " "); // add logfile break; } if (xs.EncodingMode <= 1) // 1 pass modes { if (xs.ReactionDelayFactor != 16) sb.Append("-reaction " + xs.ReactionDelayFactor + " "); if (xs.AveragingPeriod != 100) sb.Append("-averaging " + xs.AveragingPeriod + " "); if (xs.RateControlBuffer != 100) sb.Append("-smoother " + xs.RateControlBuffer + " "); } else // two pass modes { if (xs.KeyFrameBoost != 10) sb.Append("-kboost " + xs.KeyFrameBoost + " "); if (xs.KeyframeThreshold != 1) sb.Append("-kthresh " + xs.KeyframeThreshold + " "); if (xs.KeyframeReduction != 20) sb.Append("-kreduction " + xs.KeyframeReduction + " "); if (xs.OverflowControlStrength != 5) sb.Append("-ostrength " + xs.OverflowControlStrength + " "); if (xs.MaxOverflowImprovement != 5) sb.Append("-oimprove " + xs.MaxOverflowImprovement + " "); if (xs.MaxOverflowDegradation != 5) sb.Append("-odegrade " + xs.MaxOverflowDegradation + " "); if (xs.HighBitrateDegradation != 0) sb.Append("-chigh " + xs.HighBitrateDegradation + " "); if (xs.LowBitrateImprovement != 0) sb.Append("-clow " + xs.LowBitrateImprovement + " "); sb.Append("-overhead 0 "); if (xs.XvidProfile != 0) { switch (xs.XvidProfile) { case 0: break; case 1: sb.Append("-vbvmax 4854000 -vbvsize 3145728 -vbvpeak 2359296 "); break; case 2: sb.Append("-vbvmax 9708400 -vbvsize 6291456 -vbvpeak 4718592 "); break; case 3: sb.Append("-vbvmax 20000000 -vbvsize 16000000 -vbvpeak 12000000 "); break; case 4: sb.Append("-vbvmax 200000 -vbvsize 262144 -vbvpeak 196608 "); break; case 5: sb.Append("-vbvmax 600000 -vbvsize 655360 -vbvpeak 491520 "); break; case 6: if (xs.VbvBuffer != 0) sb.Append("-vbvsize " + xs.VbvBuffer + " "); if (xs.VbvMaxRate != 0) sb.Append("-vbvmax " + xs.VbvMaxRate + " "); if (xs.VbvPeakRate != 0) sb.Append("-vbvpeak " + xs.VbvPeakRate + " "); break; } } } if (xs.Turbo) sb.Append("-turbo "); if (xs.KeyframeInterval != 300) sb.Append("-max_key_interval " + xs.KeyframeInterval + " "); if (!xs.PackedBitstream) // default is on in encraw sb.Append("-nopacked "); if (xs.MotionSearchPrecision != 6) sb.Append("-quality " + xs.MotionSearchPrecision + " "); if (xs.VHQMode != 1) sb.Append("-vhqmode " + xs.VHQMode + " "); if (xs.QPel) sb.Append("-qpel "); if (xs.GMC) sb.Append("-gmc "); if (xs.QuantizerMatrix == xvidSettings.MPEGMatrix) sb.Append("-qtype 1 "); else if (xs.QuantizerMatrix != xvidSettings.H263Matrix && !string.IsNullOrEmpty(xs.QuantizerMatrix)) sb.Append("-qmatrix \"" + xs.QuantizerMatrix + "\" "); if (xs.Interlaced) { sb.Append("-interlaced "); if (xs.BottomFieldFirst) sb.Append("1 "); else sb.Append("2 "); } if (xs.HVSMasking != 0) sb.Append("-masking " + xs.HVSMasking + " "); if (!xs.Trellis) sb.Append("-notrellis "); if (!xs.ChromaMotion) sb.Append("-nochromame "); if (xs.MinQuantizer != 2) sb.Append("-imin " + xs.MinQuantizer + " "); if (xs.MaxQuantizer != 31) sb.Append("-imax " + xs.MaxQuantizer + " "); if (xs.MinPQuant != 2) sb.Append("-pmin " + xs.MinPQuant + " "); if (xs.MaxPQuant != 31) sb.Append("-pmax " + xs.MaxPQuant + " "); if (!xs.ClosedGOP) sb.Append("-noclosed_gop "); if (xs.FrameDropRatio != 0) sb.Append("-drop " + xs.FrameDropRatio + " "); if (xs.NbBframes != 2) sb.Append("-max_bframes " + xs.NbBframes + " "); if (xs.NbBframes > 0) { if (xs.VHQForBframes) sb.Append("-bvhq "); if (xs.BQuantRatio != 150) sb.Append("-bquant_ratio " + xs.BQuantRatio + " "); if (xs.BQuantOffset != 100) sb.Append("-bquant_offset " + xs.BQuantOffset + " "); if (xs.MinBQuant != 2) sb.Append("-bmin " + xs.MinBQuant + " "); if (xs.MaxBQuant != 31) sb.Append("-bmax " + xs.MaxBQuant + " "); } if (d.HasValue) // custom PAR mode { Sar s = d.Value.ToSar(hres, vres); sb.Append("-par " + s.X + ":" + s.Y + " "); } sb.Append("-threads " + xs.NbThreads + " "); if (zones != null && zones.Length > 0 && xs.CreditsQuantizer >= new decimal(1) && xs.EncodingMode != 1) // only for non CQ mode at the moment { foreach (Zone zone in zones) { if (zone.mode == ZONEMODE.Quantizer) sb.Append("-zq " + zone.startFrame + " " + zone.modifier + " "); if (zone.mode == ZONEMODE.Weight) { sb.Append("-zw " + zone.startFrame + " "); double mod = (double)zone.modifier / 100.0; sb.Append(mod.ToString(ci) + " "); } } } if (xs.EncodingMode != 2) // not 2 pass vbr first pass, add output filename and output type { string extension = Path.GetExtension(output).ToLower(); if (extension.Equals(".mkv")) sb.Append(" -mkv \"" + output + "\""); else if (extension.Equals(".avi")) sb.Append(" -avi \"" + output + "\""); else sb.Append(" -o \"" + output + "\""); } if (!xs.CustomEncoderOptions.Equals("")) // add custom encoder options sb.Append(" " + xs.CustomEncoderOptions); return sb.ToString(); }
/// <summary> /// compiles the final zone configuration based on intro end frame, credits start frame and the configured zones /// </summary> /// <param name="vSettings">the video settings containing the list of configured zones</param> /// <param name="introEndFrame">the frame where the intro ends</param> /// <param name="creditsStartFrame">the frame where the credits begin</param> /// <param name="newZones">the zones that are returned</param> /// <returns>an array of zones objects in the proper order</returns> public bool getFinalZoneConfiguration(VideoCodecSettings vSettings, int introEndFrame, int creditsStartFrame, ref Zone[] zones) { Zone introZone = new Zone(); Zone creditsZone = new Zone(); ulong nbOfFrames = getNumberOfFrames(mainForm.Video.VideoInput); bool doIntroZone = false, doCreditsZone = false; int flushZonesStart = 0, flushZonesEnd = 0; if (introEndFrame > 0) // add the intro zone { introZone.startFrame = 0; introZone.endFrame = introEndFrame; introZone.mode = ZONEMODE.Quantizer; introZone.modifier = vSettings.CreditsQuantizer; if (zones.Length > 0) { Zone z = zones[0]; if (z.startFrame > introZone.endFrame) // the first configured zone starts after the intro zone doIntroZone = true; else { flushZonesStart = 1; int numberOfConfiguredZones = zones.Length; while (flushZonesStart <= numberOfConfiguredZones)// iterate through all zones backwards until we find the first that goes with the intro { Zone conflict = zones[flushZonesStart]; if (conflict.startFrame <= introZone.endFrame) // zone starts before the end of the intro -> conflict flushZonesStart++; else break; } DialogResult dr = MessageBox.Show("Your intro zone overlaps " + flushZonesStart + " zone(s) configured\nin the codec settings.\n" + "Do you want to remove those zones and add the intro zone instead?", "Zone overlap detected", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning); if (dr == DialogResult.Yes) doIntroZone = true; else if (dr == DialogResult.Cancel) // abort return false; else // discard the intro zone flushZonesStart = 0; } } else doIntroZone = true; } if (creditsStartFrame > 0) // add the credits zone { creditsZone.startFrame = creditsStartFrame; creditsZone.endFrame = (int)nbOfFrames-1; creditsZone.mode = ZONEMODE.Quantizer; creditsZone.modifier = vSettings.CreditsQuantizer; if (zones.Length > 0) { Zone z = zones[zones.Length - 1]; // get the last zone if (z.endFrame < creditsZone.startFrame) // the last configured zone ends before the credits start zone doCreditsZone = true; else { flushZonesEnd = 1; int numberOfConfiguredZones = zones.Length; while (numberOfConfiguredZones - flushZonesEnd -1 >= 0)// iterate through all zones backwards until we find the first that goes with the credits { Zone conflict = zones[numberOfConfiguredZones - flushZonesEnd -1]; if (conflict.endFrame >= creditsZone.startFrame) // zone ends after the end of the credits -> conflict flushZonesEnd++; else break; } DialogResult dr = MessageBox.Show("Your credits zone overlaps " + flushZonesEnd + " zone(s) configured\nin the codec settings.\n" + "Do you want to remove those zones and add the credits zone instead?", "Zone overlap detected", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning); if (dr == DialogResult.Yes) doCreditsZone = true; else if (dr == DialogResult.Cancel) // abort return false; else // discard the credits zone flushZonesEnd = 0; } } else // no additional zones configured doCreditsZone = true; } int newZoneSize = zones.Length - flushZonesStart - flushZonesEnd; if (doIntroZone) newZoneSize++; if (doCreditsZone) newZoneSize++; Zone[] newZones = new Zone[newZoneSize]; int index = 0; if (doIntroZone) { newZones[index] = introZone; index++; } for (int i = flushZonesStart; i < zones.Length - flushZonesEnd; i++) { newZones[index] = zones[i]; index++; } if (doCreditsZone) { newZones[index] = creditsZone; index++; } if (vSettings is xvidSettings && newZones.Length > 0) { Zone[] xvidZones = createHelperZones(newZones, (int)nbOfFrames); if (xvidZones == null) return false; else { zones = xvidZones; return true; } } zones = newZones; return true; }
/// <summary> /// generates a videojob from the given settings /// returns the job and whether or not this is an automated job (in which case another job /// will have to be created) /// </summary> /// <param name="input">the video input (avisynth script)</param> /// <param name="output">the video output</param> /// <param name="settings">the codec settings for this job</param> /// <returns>the generated job or null if there was an error with the video source</returns> public VideoJob generateVideoJob(string input, string output, VideoCodecSettings settings, bool skipVideoCheck, Dar? dar, Zone[] zones) { VideoJob job = new VideoJob(input, output, settings, dar, zones); if (Path.GetDirectoryName(settings.Logfile).Equals("")) // no path set settings.Logfile = Path.ChangeExtension(output, ".stats"); if (job.Settings.SettingsID.Equals("x264")) mbtreeFile = Path.ChangeExtension(output, ".stats.mbtree"); if (job.Settings.EncodingMode == 4) // automated 2 pass, change type to 2 pass 2nd pass { job.Settings.EncodingMode = 3; } else if (job.Settings.EncodingMode == 8) // automated 3 pass, change type to 3 pass first pass { if (mainForm.Settings.OverwriteStats) job.Settings.EncodingMode = 7; else job.Settings.EncodingMode = 3; // 2 pass 2nd pass.. doesn't overwrite the stats file } if (!skipVideoCheck) checkVideo(job.Input); return job; }
public VideoJob generateVideoJob(string input, string output, VideoCodecSettings settings, Dar? dar, Zone[] zones) { return generateVideoJob(input, output, settings, false, dar, zones); }
/// <summary> /// takes a series of non overlapping zones and adds zones with weight 1.0 in between /// this is used for xvid which doesn't know zone end frames /// </summary> /// <param name="zones">a set of zones to be analyzed</param> /// <param name="nbOfFrames">number of frames the video source has</param> /// <returns>an array of all the zones</returns> public Zone[] createHelperZones(Zone[] zones, int nbOfFrames) { ArrayList newZones = new ArrayList(); Zone z = zones[0]; Zone newZone = new Zone(); newZone.mode = ZONEMODE.Weight; newZone.modifier = (decimal)100; if (z.startFrame > 0) // zone doesn't start at the beginning, add zone before the first configured zone { newZone.startFrame = 0; newZone.endFrame = z.startFrame - 1; newZones.Add(newZone); } if (zones.Length == 1) // special case { newZones.Add(z); if (z.endFrame < nbOfFrames -1) // we hav to add an end zone { newZone.startFrame = z.endFrame + 1; newZone.endFrame = nbOfFrames - 1; newZones.Add(newZone); } } else if (zones.Length == 2) { newZones.Add(z); Zone second = zones[1]; if (z.endFrame + 1 < second.startFrame) // new zone needs to go in between { newZone.startFrame = z.endFrame + 1; newZone.endFrame = second.startFrame - 1; newZones.Add(newZone); } newZones.Add(second); if (second.endFrame < nbOfFrames - 1) // add end zone { newZone.startFrame = second.endFrame + 1; newZone.endFrame = nbOfFrames - 1; newZones.Add(newZone); } } else { for (int i = 0; i <= zones.Length - 2; i++) { Zone first = zones[i]; Zone second = zones[i+1]; if (first.endFrame + 1 == second.startFrame) // zones are adjacent { newZones.Add(first); continue; } else // zones are not adjacent, create filler zone { newZone.startFrame = first.endFrame + 1; newZone.endFrame = second.startFrame - 1; newZones.Add(first); newZones.Add(newZone); } } z = zones[zones.Length - 1]; newZones.Add(z); if (z.endFrame != nbOfFrames - 1) // we have to add another zone extending till the end of the video { newZone.startFrame = z.endFrame + 1; newZone.endFrame = nbOfFrames - 1; newZones.Add(newZone); } } Zone[] retval = new Zone[newZones.Count]; int index = 0; foreach (object o in newZones) { z = (Zone)o; if (index < 64) { retval[index] = z; index++; } else { DialogResult dr = MessageBox.Show("XviD only supports 64 zones. Including filler zones your current\r\nconfiguration yields " + retval.Length + " zones. Do you want to discard the " + "remaining zones?\r\nPress Cancel to reconfigure your zones. Keep in mind that if you have no adjacent zones, a filler zone will have to be added\r\nso 32 non adjacent zones is the " + "maximum number of zones you can have. Both intro and credits region also require a zone.", "Too many zones", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning); if (dr == DialogResult.OK) break; else // user wants to abort return null; } } return retval; }
public bool AddVideoJobs(string movieInput, string movieOutput, VideoCodecSettings settings, int introEndFrame, int creditsStartFrame, Dar? dar, bool prerender, bool checkVideo, Zone[] zones) { bool cont = getFinalZoneConfiguration(settings, introEndFrame, creditsStartFrame, ref zones); if (!cont) // abort return false; JobChain jobs = prepareVideoJob(movieInput, movieOutput, settings, dar, prerender, checkVideo, zones); if (jobs == null) return false; mainForm.Jobs.addJobsWithDependencies(jobs); return false; }