/// <summary> /// Generates commandline arguments used for encoding an video stream to h.264 format. /// Input is either stdin or file/avisynth script. /// </summary> /// <param name="inProfile">Encoding profile</param> /// <param name="bitrate">Target bitrate</param> /// <param name="hRes">Video width</param> /// <param name="vRes">Video height</param> /// <param name="pass">Encoding pass</param> /// <param name="fpsN">Framerate numerator</param> /// <param name="fpsD">Framerate denominator</param> /// <param name="stereo">Defines, which stereo encoding mode should be used</param> /// <param name="format">Image format</param> /// <param name="inFile">Path to input file</param> /// <param name="outFile">Path to output file</param> /// <returns>Commandline arguments</returns> public static string Generate(X264Profile inProfile, int bitrate, int hRes, int vRes, int pass, int fpsN, int fpsD, StereoEncoding stereo = StereoEncoding.None, VideoFormat format = VideoFormat.Unknown, string inFile = "input", string outFile = "output") { StringBuilder sb = new StringBuilder(); if (inProfile != null) { bool display; X264Device device = X264Device.CreateDeviceList()[inProfile.TuneDevice]; // AVC Profiles switch (inProfile.AVCProfile) { case 0: sb.Append("--profile baseline "); break; case 1: sb.Append("--profile main "); break; default: sb.Append("--profile high "); break; } // AVC Levels if (inProfile.AVCLevel != 15) // unrestricted sb.AppendFormat("--level {0} ", CLILevelNames[inProfile.AVCLevel]); // Blu-Ray compatibility if (inProfile.UseBluRayCompatibility) sb.Append("--bluray-compat "); // x264 Presets if (!inProfile.CustomCommandLine.Contains("--preset")) { switch (inProfile.Preset) { case 0: sb.Append("--preset ultrafast "); break; case 1: sb.Append("--preset superfast "); break; case 2: sb.Append("--preset veryfast "); break; case 3: sb.Append("--preset faster "); break; case 4: sb.Append("--preset fast "); break; //case 5: sb.Append("--preset medium "); break; // default value case 6: sb.Append("--preset slow "); break; case 7: sb.Append("--preset slower "); break; case 8: sb.Append("--preset veryslow "); break; case 9: sb.Append("--preset placebo "); break; } } // x264 Tunings if (!inProfile.CustomCommandLine.Contains("--tune")) { switch (inProfile.Tuning) { 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; } } // Encoding Modes int tempPass = pass; int tempBitrate = bitrate; int vbvBuf = GetVBVMaxrate(inProfile, device); if (tempBitrate <= 0) tempBitrate = inProfile.VBRSetting; if (vbvBuf > 0 && tempBitrate > vbvBuf) // limit Bitrate to max vbvbuf size tempBitrate = vbvBuf; switch (inProfile.EncodingMode) { case 0: // ABR if (!inProfile.CustomCommandLine.Contains("--bitrate")) sb.AppendFormat(AppSettings.CInfo, "--bitrate {0:0} ", tempBitrate); break; case 1: // Constant Quantizer if (!inProfile.CustomCommandLine.Contains("--qp")) sb.AppendFormat(AppSettings.CInfo, "--qp {0:0}", inProfile.QuantizerSetting); break; case 2: // automated 2 pass case 3: // automated 3 pass sb.AppendFormat(AppSettings.CInfo, "--pass {0:0} --bitrate {1:0} ", tempPass, tempBitrate); break; default: if (!inProfile.CustomCommandLine.Contains("--crf") && inProfile.QualitySetting != 23) sb.AppendFormat(AppSettings.CInfo, "--crf {0:0} ", inProfile.QualitySetting); break; } // Slow 1st Pass if (!inProfile.CustomCommandLine.Contains("--slow-firstpass")) if ((inProfile.UseSlowFirstPass) && inProfile.Preset < 9 && // 9 = placebo ((inProfile.EncodingMode == 2) || // automated twopass (inProfile.EncodingMode == 3))) // automated threepass sb.Append("--slow-firstpass "); // Threads if (!inProfile.CustomCommandLine.Contains("--thread-input")) if (inProfile.UseThreadInput && inProfile.NumThreads == 1) sb.Append("--thread-input "); if (!inProfile.CustomCommandLine.Contains("--threads")) if (inProfile.NumThreads > 0) sb.AppendFormat(AppSettings.CInfo, "--threads {0:0} ", inProfile.NumThreads); #region frame-type tab // H.264 Features if (inProfile.UseDeblocking) { display = false; switch (inProfile.Tuning) { case 1: if (inProfile.DeblockingStrength != -1 || inProfile.DeblockingThreshold != -1) display = true; break; // film case 2: if (inProfile.DeblockingStrength != 1 || inProfile.DeblockingThreshold != 1) display = true; break; // animation case 3: if (inProfile.DeblockingStrength != -2 || inProfile.DeblockingThreshold != -2) display = true; break; // grain default: if (inProfile.DeblockingStrength != 0 || inProfile.DeblockingThreshold != 0) display = true; break; } if (!inProfile.CustomCommandLine.Contains("--deblock ")) if (display) sb.AppendFormat(AppSettings.CInfo, "--deblock {0:0}:{1:0} ", inProfile.DeblockingStrength, inProfile.DeblockingThreshold); } else { if (!inProfile.CustomCommandLine.Contains("--no-deblock")) if (inProfile.Preset != 0 && inProfile.Tuning != 7) // ultrafast preset and not fast decode tuning sb.Append("--no-deblock "); } if (inProfile.AVCProfile > 0 && !inProfile.CustomCommandLine.Contains("--no-cabac")) { if (!inProfile.UseCabac) { if (inProfile.Preset != 0 && inProfile.Tuning != 7) // ultrafast preset and not fast decode tuning sb.Append("--no-cabac "); } } // GOP Size int backupMaxGopSize = inProfile.MaxGopSize; int backupMinGopSize = inProfile.MinGopSize; inProfile.MaxGopSize = GetKeyInt(fpsN, fpsD, backupMaxGopSize, device, inProfile.GopCalculation); if (inProfile.MaxGopSize != 250) // default size { if (inProfile.MaxGopSize == 0) sb.Append("--keyint infinite "); else sb.AppendFormat(AppSettings.CInfo, "--keyint {0:0} ", inProfile.MaxGopSize); } if (!inProfile.UseBluRayCompatibility) { inProfile.MinGopSize = GetMinKeyInt(fpsN, fpsD, backupMinGopSize, inProfile.MaxGopSize, device, inProfile.GopCalculation); if (inProfile.MinGopSize > (inProfile.MaxGopSize / 2 + 1)) { inProfile.MinGopSize = inProfile.MaxGopSize / 2 + 1; } int Default = Math.Min(inProfile.MaxGopSize / 10, fpsN / fpsD); if (inProfile.MinGopSize != Default) // (MIN(--keyint / 10,--fps)) is default sb.AppendFormat(AppSettings.CInfo, "--min-keyint {0:0} ", inProfile.MinGopSize); } inProfile.MaxGopSize = backupMaxGopSize; inProfile.MinGopSize = backupMinGopSize; if (!inProfile.CustomCommandLine.Contains("--open-gop") && (inProfile.UseOpenGop || inProfile.UseBluRayCompatibility)) sb.Append("--open-gop "); // B-Frames inProfile.NumBFrames = GetBFrames(inProfile, device); if (inProfile.AVCProfile > 0 && inProfile.NumBFrames != X264Settings.GetDefaultNumberOfBFrames(inProfile.AVCLevel, inProfile.Tuning, inProfile.AVCProfile, device)) sb.AppendFormat(AppSettings.CInfo, "--bframes {0:0} ", inProfile.NumBFrames); if (inProfile.NumBFrames > 0) { if (!inProfile.CustomCommandLine.Contains("--b-adapt")) { display = false; if (inProfile.Preset > 5) // medium { if (inProfile.AdaptiveBFrames != 2) display = true; } else if (inProfile.Preset > 0) // ultrafast { if (inProfile.AdaptiveBFrames != 1) display = true; } else { if (inProfile.AdaptiveBFrames != 0) display = true; } if (display) sb.AppendFormat(AppSettings.CInfo, "--b-adapt {0:0} ", inProfile.AdaptiveBFrames); } inProfile.BPyramid = GetBPyramid(inProfile, device); if (inProfile.NumBFrames > 1 && (inProfile.BPyramid != 2 && !inProfile.UseBluRayCompatibility || inProfile.BPyramid != 1 && inProfile.UseBluRayCompatibility)) { switch (inProfile.BPyramid) // 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 (!inProfile.CustomCommandLine.Contains("--no-weightb")) if (!inProfile.UseWeightedPred && inProfile.Tuning != 7 && inProfile.Preset != 0) // no weightpredb + tuning != fastdecode + preset != ultrafast sb.Append("--no-weightb "); } // B-Frames bias if (!inProfile.CustomCommandLine.Contains("--b-bias ")) if (inProfile.BFrameBias != 0) sb.AppendFormat(AppSettings.CInfo, "--b-bias {0:0} ", inProfile.BFrameBias); // Other if (inProfile.UseAdaptiveIFrameDecision) { if (!inProfile.CustomCommandLine.Contains("--scenecut ")) if (inProfile.NumExtraIFrames != 40 && inProfile.Preset != 0 || inProfile.NumExtraIFrames != 0 && inProfile.Preset == 0) sb.AppendFormat(AppSettings.CInfo, "--scenecut {0:0} ", inProfile.NumExtraIFrames); } else { if (!inProfile.CustomCommandLine.Contains("--no-scenecut")) if (inProfile.Preset != 0) sb.Append("--no-scenecut "); } // reference frames int iRefFrames = GetRefFrames(hRes, vRes, inProfile, device); if (iRefFrames != X264Settings.GetDefaultNumberOfRefFrames(inProfile.Preset, inProfile.Tuning, null, inProfile.AVCLevel, hRes, vRes)) sb.AppendFormat(AppSettings.CInfo, "--ref {0:0} ", iRefFrames); // WeightedPPrediction inProfile.PFrameWeightedPrediction = GetWeightp(inProfile, device); if (inProfile.PFrameWeightedPrediction != X264Settings.GetDefaultNumberOfWeightp(inProfile.Preset, inProfile.Tuning, inProfile.AVCProfile, inProfile.UseBluRayCompatibility)) sb.AppendFormat(AppSettings.CInfo, "--weightp {0:0} ", inProfile.PFrameWeightedPrediction); // Slicing inProfile.NumSlices = GetSlices(inProfile, device); if (inProfile.NumSlices != 0) sb.AppendFormat(AppSettings.CInfo, "--slices {0:0} ", inProfile.NumSlices); if (!inProfile.CustomCommandLine.Contains("--slice-max-size ")) if (inProfile.MaxSliceSizeBytes != 0) sb.AppendFormat(AppSettings.CInfo, "--slice-max-size {0:0} ", inProfile.MaxSliceSizeBytes); if (!inProfile.CustomCommandLine.Contains("--slice-max-mbs ")) if (inProfile.MaxSliceSizeBlocks != 0) sb.AppendFormat(AppSettings.CInfo, "--slice-max-mbs {0:0} ", inProfile.MaxSliceSizeBlocks); #endregion #region rc tab if (!inProfile.CustomCommandLine.Contains("--qpmin")) if (inProfile.QuantizerMin != 0) sb.AppendFormat(AppSettings.CInfo, "--qpmin {0:0} ", inProfile.QuantizerMin); if (!inProfile.CustomCommandLine.Contains("--qpmax")) if (inProfile.QuantizerMax != 69) sb.AppendFormat(AppSettings.CInfo, "--qpmax {0:0} ", inProfile.QuantizerMax); if (!inProfile.CustomCommandLine.Contains("--qpstep")) if (inProfile.QuantizerDelta != 4) sb.AppendFormat(AppSettings.CInfo, "--qpstep {0:0} ", inProfile.QuantizerDelta); if (Math.Abs(inProfile.QuantizerRatioIP - 1.4F) > 0) { display = true; if (inProfile.Tuning == 3 && Math.Abs(inProfile.QuantizerRatioIP - 1.1F) <= 0) display = false; if (!inProfile.CustomCommandLine.Contains("--ipratio")) if (display) sb.AppendFormat(AppSettings.CInfo, "--ipratio {0:0} ", inProfile.QuantizerRatioIP); } if (Math.Abs(inProfile.QuantizerRatioPB - 1.3F) > 0) { display = true; if (inProfile.Tuning == 3 && Math.Abs(inProfile.QuantizerRatioPB - 1.1F) <= 0) display = false; if (!inProfile.CustomCommandLine.Contains("--pbratio")) if (display) sb.AppendFormat(AppSettings.CInfo, "--pbratio {0:0} ", inProfile.QuantizerRatioPB); } if (!inProfile.CustomCommandLine.Contains("--chroma-qp-offset")) if (inProfile.ChromaQPOffset != 0) sb.AppendFormat(AppSettings.CInfo, "--chroma-qp-offset {0:0} ", inProfile.ChromaQPOffset); if (inProfile.EncodingMode != 1) // doesn't apply to CQ mode { inProfile.VBVBufSize = GetVBVBufsize(inProfile, device); if (inProfile.VBVBufSize > 0) sb.AppendFormat(AppSettings.CInfo, "--vbv-bufsize {0:0} ", inProfile.VBVBufSize); inProfile.VBVMaxRate = GetVBVMaxrate(inProfile, device); if (inProfile.VBVMaxRate > 0) sb.AppendFormat(AppSettings.CInfo, "--vbv-maxrate {0:0} ", inProfile.VBVMaxRate); if (!inProfile.CustomCommandLine.Contains("--vbv-init")) if (Math.Abs(inProfile.VBVInitialBuffer - 0.9F) > 0) sb.AppendFormat(AppSettings.CInfo, "--vbv-init {0:0.0} ", inProfile.VBVInitialBuffer); if (!inProfile.CustomCommandLine.Contains("--ratetol")) if (Math.Abs(inProfile.BitrateVariance - 1.0F) > 0) sb.AppendFormat(AppSettings.CInfo, "--ratetol {0:0.0} ", inProfile.BitrateVariance); if (!inProfile.CustomCommandLine.Contains("--qcomp")) { display = true; if ((inProfile.Tuning == 3 && Math.Abs(inProfile.QuantizerCompression - 0.8F) <= 0) || (inProfile.Tuning != 3 && Math.Abs(inProfile.QuantizerCompression - 0.6F) <= 0)) display = false; if (display) sb.AppendFormat(AppSettings.CInfo, "--qcomp {0:0.0} ", inProfile.QuantizerCompression); } if (inProfile.EncodingMode > 1) // applies only to twopass { if (!inProfile.CustomCommandLine.Contains("--cplxblur")) if (inProfile.TempBlurFrameComplexity != 20) sb.AppendFormat(AppSettings.CInfo, "--cplxblur {0:0} ", inProfile.TempBlurFrameComplexity); if (!inProfile.CustomCommandLine.Contains("--qblur")) if (Math.Abs(inProfile.TempBlurQuant - 0.5F) > 0) sb.AppendFormat(AppSettings.CInfo, "--qblur {0:0.0} ", inProfile.TempBlurQuant); } } // Dead Zones if (!inProfile.CustomCommandLine.Contains("--deadzone-inter")) { display = true; if ((inProfile.Tuning != 3 && inProfile.DeadZoneInter == 21 && inProfile.DeadZoneIntra == 11) || (inProfile.Tuning == 3 && inProfile.DeadZoneInter == 6 && inProfile.DeadZoneIntra == 6)) display = false; if (display) sb.AppendFormat(AppSettings.CInfo, "--deadzone-inter {0:0} ", inProfile.DeadZoneInter); } if (!inProfile.CustomCommandLine.Contains("--deadzone-intra")) { display = true; if ((inProfile.Tuning != 3 && inProfile.DeadZoneIntra == 11) || (inProfile.Tuning == 3 && inProfile.DeadZoneIntra == 6)) display = false; if (display) sb.AppendFormat(AppSettings.CInfo, "--deadzone-intra {0:0} ", inProfile.DeadZoneIntra); } // Disable Macroblok Tree if (!inProfile.UseMBTree) { if (!inProfile.CustomCommandLine.Contains("--no-mbtree")) if (inProfile.Preset > 0) // preset veryfast sb.Append("--no-mbtree "); } else { // RC Lookahead if (!inProfile.CustomCommandLine.Contains("--rc-lookahead")) { display = false; switch (inProfile.Preset) { case 0: case 1: if (inProfile.NumFramesLookahead != 0) display = true; break; case 2: if (inProfile.NumFramesLookahead != 10) display = true; break; case 3: if (inProfile.NumFramesLookahead != 20) display = true; break; case 4: if (inProfile.NumFramesLookahead != 30) display = true; break; case 5: if (inProfile.NumFramesLookahead != 40) display = true; break; case 6: if (inProfile.NumFramesLookahead != 50) display = true; break; case 7: case 8: case 9: if (inProfile.NumFramesLookahead != 60) display = true; break; } if (display) sb.AppendFormat("--rc-lookahead {0:0} ", inProfile.NumFramesLookahead); } } // AQ-Mode if (inProfile.EncodingMode != 1) { if (!inProfile.CustomCommandLine.Contains("--aq-mode")) { if (inProfile.AdaptiveQuantizersMode != X264Settings.GetDefaultAQMode(inProfile.Preset, inProfile.Tuning)) sb.AppendFormat("--aq-mode {0:0} ", inProfile.AdaptiveQuantizersMode); } if (inProfile.AdaptiveQuantizersMode > 0) { display = false; switch (inProfile.Tuning) { case 2: if (Math.Abs(inProfile.AdaptiveQuantizersStrength - 0.6F) > 0) display = true; break; case 3: if (Math.Abs(inProfile.AdaptiveQuantizersStrength - 0.5F) > 0) display = true; break; case 7: if (Math.Abs(inProfile.AdaptiveQuantizersStrength - 1.3F) > 0) display = true; break; default: if (Math.Abs(inProfile.AdaptiveQuantizersStrength - 1.0F) > 0) display = true; break; } if (!inProfile.CustomCommandLine.Contains("--aq-strength")) if (display) sb.AppendFormat(AppSettings.CInfo, "--aq-strength {0:0.0} ", inProfile.AdaptiveQuantizersStrength); } } // custom matrices if (inProfile.AVCProfile > 1 && inProfile.QuantizerMatrix > 0) { switch (inProfile.QuantizerMatrix) { case 1: if (!inProfile.CustomCommandLine.Contains("--cqm")) sb.Append("--cqm \"jvt\" "); break; } } #endregion #region analysis tab // Disable Chroma Motion Estimation if (!inProfile.CustomCommandLine.Contains("--no-chroma-me")) if (!inProfile.UseChromaMotionEstimation) sb.Append("--no-chroma-me "); // Motion Estimation Range if (!inProfile.CustomCommandLine.Contains("--merange")) { if ((inProfile.Preset <= 7 && inProfile.MotionEstimationRange != 16) || (inProfile.Preset >= 8 && inProfile.MotionEstimationRange != 24)) sb.AppendFormat("--merange {0:0} ", inProfile.MotionEstimationRange); } // ME Type if (!inProfile.CustomCommandLine.Contains("--me ")) { display = false; switch (inProfile.Preset) { case 0: case 1: if (inProfile.MotionEstimationAlgorithm != 0) display = true; break; case 2: case 3: case 4: case 5: if (inProfile.MotionEstimationAlgorithm != 1) display = true; break; case 6: case 7: case 8: if (inProfile.MotionEstimationAlgorithm != 2) display = true; break; case 9: if (inProfile.MotionEstimationAlgorithm != 4) display = true; break; } if (display) { switch (inProfile.MotionEstimationAlgorithm) { 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 (!inProfile.CustomCommandLine.Contains("--direct ")) { display = false; if (inProfile.Preset > 5) // preset medium { if (inProfile.MVPredictionMod != 3) display = true; } else if (inProfile.MVPredictionMod != 1) display = true; if (display) { switch (inProfile.MVPredictionMod) { 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 (!inProfile.CustomCommandLine.Contains("--nr ")) if (inProfile.NoiseReduction > 0) sb.AppendFormat("--nr {0:0} ", inProfile.NoiseReduction); // subpel refinement if (!inProfile.CustomCommandLine.Contains("--subme ")) { display = false; switch (inProfile.Preset) { case 0: if (inProfile.SubPixelRefinement != 0) display = true; break; case 1: if (inProfile.SubPixelRefinement != 1) display = true; break; case 2: if (inProfile.SubPixelRefinement != 2) display = true; break; case 3: if (inProfile.SubPixelRefinement != 4) display = true; break; case 4: if (inProfile.SubPixelRefinement != 6) display = true; break; case 5: if (inProfile.SubPixelRefinement != 7) display = true; break; case 6: if (inProfile.SubPixelRefinement != 8) display = true; break; case 7: if (inProfile.SubPixelRefinement != 9) display = true; break; case 8: if (inProfile.SubPixelRefinement != 10) display = true; break; case 9: if (inProfile.SubPixelRefinement != 11) display = true; break; } if (display) sb.AppendFormat("--subme {0:0} ", inProfile.SubPixelRefinement); } // macroblock types if (!inProfile.CustomCommandLine.Contains("--partitions ")) { bool bExpectedP8X8Mv = true; bool bExpectedB8X8Mv = true; bool bExpectedI4X4Mv = true; bool bExpectedI8X8Mv = true; bool bExpectedP4X4Mv = true; switch (inProfile.Preset) { case 0: bExpectedP8X8Mv = false; bExpectedB8X8Mv = false; bExpectedI4X4Mv = false; bExpectedI8X8Mv = false; bExpectedP4X4Mv = false; break; case 1: bExpectedP8X8Mv = false; bExpectedB8X8Mv = false; bExpectedP4X4Mv = false; break; case 2: case 3: case 4: case 5: case 6: bExpectedP4X4Mv = false; break; } if (inProfile.Tuning == 7 && bExpectedP8X8Mv) bExpectedP4X4Mv = true; if (inProfile.AVCProfile < 2) bExpectedI8X8Mv = false; if (bExpectedP8X8Mv != inProfile.MacroBlocksPartitionsP8X8 || bExpectedB8X8Mv != inProfile.MacroBlocksPartitionsB8X8 || bExpectedI4X4Mv != inProfile.MacroBlocksPartitionsI4X4 || bExpectedI8X8Mv != inProfile.MacroBlocksPartitionsI8X8 || bExpectedP4X4Mv != inProfile.MacroBlocksPartitionsP4X4) { if (inProfile.MacroBlocksPartitionsP8X8 || inProfile.MacroBlocksPartitionsB8X8 || inProfile.MacroBlocksPartitionsI4X4 || inProfile.MacroBlocksPartitionsI8X8 || inProfile.MacroBlocksPartitionsP4X4) { sb.Append("--partitions "); if (inProfile.MacroBlocksPartitionsI4X4 && inProfile.MacroBlocksPartitionsI8X8 && inProfile.MacroBlocksPartitionsP4X4 && inProfile.MacroBlocksPartitionsP8X8 && inProfile.MacroBlocksPartitionsB8X8) sb.Append("all "); else { if (inProfile.MacroBlocksPartitionsP8X8) // default is checked sb.Append("p8x8,"); if (inProfile.MacroBlocksPartitionsB8X8) // default is checked sb.Append("b8x8,"); if (inProfile.MacroBlocksPartitionsI4X4) // default is checked sb.Append("i4x4,"); if (inProfile.MacroBlocksPartitionsP4X4) // default is unchecked sb.Append("p4x4,"); if (inProfile.MacroBlocksPartitionsI8X8) // 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 (inProfile.AVCProfile > 1 && !inProfile.CustomCommandLine.Contains("--no-8x8dct")) if (!inProfile.MacroBlocksPartitionsAdaptiveDCT) if (inProfile.Preset > 0) sb.Append("--no-8x8dct "); // Trellis if (!inProfile.CustomCommandLine.Contains("--trellis ")) { display = false; switch (inProfile.Preset) { case 0: case 1: case 2: if (inProfile.Trellis != 0) display = true; break; case 3: case 4: case 5: case 6: if (inProfile.Trellis != 1) display = true; break; case 7: case 8: case 9: if (inProfile.Trellis != 2) display = true; break; } if (display) sb.AppendFormat("--trellis {0:0} ", inProfile.Trellis); } if (!inProfile.CustomCommandLine.Contains("--psy-rd ")) { if (inProfile.SubPixelRefinement > 5) { display = false; switch (inProfile.Tuning) { case 1: if ((Math.Abs(inProfile.PsyRDStrength - 1.0F) > 0) || (Math.Abs(inProfile.PsyTrellisStrength - 0.15F) > 0)) display = true; break; case 2: if ((Math.Abs(inProfile.PsyRDStrength - 0.4F) > 0) || (Math.Abs(inProfile.PsyTrellisStrength - 0.0F) > 0)) display = true; break; case 3: if ((Math.Abs(inProfile.PsyRDStrength - 1.0F) > 0) || (Math.Abs(inProfile.PsyTrellisStrength - 0.25F) > 0)) display = true; break; case 7: if ((Math.Abs(inProfile.PsyRDStrength - 1.0F) > 0) || (Math.Abs(inProfile.PsyTrellisStrength - 0.2F) > 0)) display = true; break; default: if ((Math.Abs(inProfile.PsyRDStrength - 1.0F) > 0) || (Math.Abs(inProfile.PsyTrellisStrength - 0.0F) > 0)) display = true; break; } if (display) sb.AppendFormat(AppSettings.CInfo, "--psy-rd {0:0.00}:{1:0.00} ", inProfile.PsyRDStrength, inProfile.PsyTrellisStrength); } } if (!inProfile.CustomCommandLine.Contains("--no-mixed-refs")) if (inProfile.UseNoMixedReferenceFrames) if (inProfile.Preset >= 4) // preset fast sb.Append("--no-mixed-refs "); if (!inProfile.CustomCommandLine.Contains("--no-dct-decimate")) if (inProfile.UseNoDCTDecimation) if (inProfile.Tuning != 3) // tune grain sb.Append("--no-dct-decimate "); if (!inProfile.CustomCommandLine.Contains("--no-fast-pskip")) if (inProfile.UseNoFastPSkip) if (inProfile.Preset != 9) // preset placebo sb.Append("--no-fast-pskip "); if (!inProfile.CustomCommandLine.Contains("--no-psy")) if (inProfile.UseNoPsychovisualEnhancements && (inProfile.Tuning != 5 && inProfile.Tuning != 6)) sb.Append("--no-psy "); inProfile.UseAccessUnitDelimiters = GetAud(inProfile, device); if (inProfile.UseAccessUnitDelimiters && !inProfile.UseBluRayCompatibility) sb.Append("--aud "); inProfile.HRDInfo = GetNalHrd(inProfile, device); switch (inProfile.HRDInfo) { case 1: if (!inProfile.UseBluRayCompatibility) sb.Append("--nal-hrd vbr "); break; case 2: sb.Append("--nal-hrd cbr "); break; } if (!inProfile.CustomCommandLine.Contains("--non-deterministic")) if (inProfile.UseNonDeterministic) sb.Append("--non-deterministic "); #endregion #region misc tab if (!inProfile.CustomCommandLine.Contains("--psnr")) if (inProfile.UsePSNRCalculation) sb.Append("--psnr "); if (!inProfile.CustomCommandLine.Contains("--ssim")) if (inProfile.UseSSIMCalculation) sb.Append("--ssim "); if (!inProfile.CustomCommandLine.Contains("--range ")) switch (inProfile.VUIRange) { case 1: sb.AppendFormat("--range tv "); break; case 2: sb.Append("--range pc "); break; } #endregion #region input / ouput / custom string customSarValue = string.Empty; Dar? d = new Dar((ulong)hRes, (ulong)vRes); if (inProfile.UseAutoSelectSAR) { int tempValue = GetSar(inProfile, d, hRes, vRes, out customSarValue, String.Empty); inProfile.ForceSAR = tempValue; } if (inProfile.UseAutoSelectColorSettings) { inProfile.ColorPrimaries = GetColorprim(inProfile, format); inProfile.Transfer = GetTransfer(inProfile, format); inProfile.ColorMatrix = GetColorMatrix(inProfile, format); } if (device.BluRay) { if (inProfile.InterlaceMode < 2) inProfile.InterlaceMode = GetInterlacedMode(format); inProfile.UseFakeInterlaced = GetFakeInterlaced(inProfile, format, fpsN, fpsD); inProfile.UseForcePicStruct = GetPicStruct(inProfile, format); inProfile.Pulldown = GetPulldown(inProfile, format, fpsN, fpsD); } else { if (inProfile.InterlaceMode == 0) inProfile.InterlaceMode = GetInterlacedMode(format); if (inProfile.Pulldown == 0) inProfile.Pulldown = GetPulldown(inProfile, format, fpsN, fpsD); } if (!inProfile.CustomCommandLine.Contains("--bff") && !inProfile.CustomCommandLine.Contains("--tff")) { switch (inProfile.InterlaceMode) { case 2: sb.Append("--bff "); break; case 3: sb.Append("--tff "); break; } } if (!inProfile.CustomCommandLine.Contains("--fake-interlaced")) { if (inProfile.UseFakeInterlaced && inProfile.InterlaceMode == 1) sb.Append("--fake-interlaced "); } if (!inProfile.CustomCommandLine.Contains("--pic-struct")) { if (inProfile.UseForcePicStruct && inProfile.InterlaceMode == 1 && inProfile.Pulldown == 0) sb.Append("--pic-struct "); } if (!inProfile.CustomCommandLine.Contains("--colorprim")) { switch (inProfile.ColorPrimaries) { case 0: break; case 1: sb.Append("--colorprim bt709 "); break; case 2: sb.Append("--colorprim bt470m "); break; case 3: sb.Append("--colorprim bt470bg "); break; case 4: sb.Append("--colorprim smpte170m "); break; case 5: sb.Append("--colorprim smpte240m "); break; case 6: sb.Append("--colorprim film "); break; } } if (!inProfile.CustomCommandLine.Contains("--transfer")) { switch (inProfile.Transfer) { case 0: break; case 1: sb.Append("--transfer bt709 "); break; case 2: sb.Append("--transfer bt470m "); break; case 3: sb.Append("--transfer bt470bg "); break; case 4: sb.Append("--transfer linear "); break; case 5: sb.Append("--transfer log100 "); break; case 6: sb.Append("--transfer log316 "); break; case 7: sb.Append("--transfer smpte170m "); break; case 8: sb.Append("--transfer smpte240m "); break; } } if (!inProfile.CustomCommandLine.Contains("--colormatrix")) { switch (inProfile.ColorMatrix) { case 0: break; case 1: sb.Append("--colormatrix bt709 "); break; case 2: sb.Append("--colormatrix fcc "); break; case 3: sb.Append("--colormatrix bt470bg "); break; case 4: sb.Append("--colormatrix smpte170m "); break; case 5: sb.Append("--colormatrix smpte240m "); break; case 6: sb.Append("--colormatrix GBR "); break; case 7: sb.Append("--colormatrix YCgCo "); break; } } if (!inProfile.CustomCommandLine.Contains("--pulldown")) { switch (inProfile.Pulldown) { case 0: break; case 1: break; case 2: sb.Append("--pulldown 22 "); break; case 3: sb.Append("--pulldown 32 "); break; case 4: sb.Append("--pulldown 64 "); break; case 5: sb.Append("--pulldown double "); break; case 6: sb.Append("--pulldown triple "); break; case 7: sb.Append("--pulldown euro "); break; } } if (!String.IsNullOrEmpty(inProfile.CustomCommandLine)) // add custom encoder options sb.Append(Regex.Replace(inProfile.CustomCommandLine, @"\r\n?|\n", string.Empty).Trim() + " "); if (!inProfile.CustomCommandLine.Contains("--sar")) { switch (inProfile.ForceSAR) { case 0: { if (!String.IsNullOrEmpty(customSarValue)) sb.Append("--sar " + customSarValue + " "); break; } case 1: sb.Append("--sar 1:1 "); break; case 2: sb.Append("--sar 4:3 "); break; case 3: sb.Append("--sar 8:9 "); break; case 4: sb.Append("--sar 10:11 "); break; case 5: sb.Append("--sar 12:11 "); break; case 6: sb.Append("--sar 16:11 "); break; case 7: sb.Append("--sar 32:27 "); break; case 8: sb.Append("--sar 40:33 "); break; case 9: sb.Append("--sar 64:45 "); break; } } if (!inProfile.CustomCommandLine.Contains("--frame-packing")) { if (stereo != StereoEncoding.None) sb.Append("--frame-packing 3 "); } //add the rest of the commandline regarding the output if ((inProfile.EncodingMode == 2 || inProfile.EncodingMode == 3) && (tempPass == 1)) sb.Append("--output NUL "); else if (!String.IsNullOrEmpty(outFile)) sb.AppendFormat("--output \"{0}\" ", outFile); if (!String.IsNullOrEmpty(inFile)) { if (String.CompareOrdinal(inFile, "-") == 0) sb.AppendFormat("--demuxer y4m - "); else sb.AppendFormat("\"{0}\" ", inFile); } #endregion } return sb.ToString(); }
private static int GetSar(X264Profile inProfile, Dar? d, int hRes, int vRes, out string customSarValue, string customSarValueInput) { string strCustomValue = string.Empty; int sar = inProfile.ForceSAR; customSarValue = String.Empty; if (String.IsNullOrEmpty(customSarValueInput)) { switch (strCustomValue.ToLower()) { case "1:1": sar = 1; break; case "4:3": sar = 2; break; case "8:9": sar = 3; break; case "10:11": sar = 4; break; case "12:11": sar = 5; break; case "16:11": sar = 6; break; case "32:27": sar = 7; break; case "40:33": sar = 8; break; case "64:45": sar = 9; break; default: customSarValue = strCustomValue; sar = 0; break; } } if (d.HasValue && sar == 0 && String.IsNullOrEmpty(customSarValue) && String.IsNullOrEmpty(customSarValueInput)) { Sar s = d.Value.ToSar(hRes, vRes); switch (s.X + ":" + s.Y) { case "1:1": sar = 1; break; case "4:3": sar = 2; break; case "8:9": sar = 3; break; case "10:11": sar = 4; break; case "12:11": sar = 5; break; case "16:11": sar = 6; break; case "32:27": sar = 7; break; case "40:33": sar = 8; break; case "64:45": sar = 9; break; default: customSarValue = s.X + ":" + s.Y; break; } } return sar; }