Beispiel #1
0
        /// <summary>
        /// Moves specified settings file as preview files.
        /// </summary>
        /// <param name="settings">The settings to use for re-encoding.</param>
        public async Task MovePreviewFilesAsync(MediaEncoderSettings settings)
        {
            await DeletePreviewFilesAsync();

            if (settings.ConvertToAvi)
            {
                File.Move(settings.InputFile, PathManager.PreviewSourceFile);
            }
            if (settings.Deshaker && File.Exists(settings.DeshakerLog))
            {
                File.Move(settings.DeshakerLog, PathManager.PreviewDeshakerLog);
            }
            if (!string.IsNullOrEmpty(settings.CustomScript) && (settings.ConvertToAvi || settings.Deshaker))
            {
                AviSynthScriptBuilder Script = new AviSynthScriptBuilder(settings.CustomScript);
                if (settings.ConvertToAvi)
                {
                    Script.Replace(Script.GetAsciiPath(settings.InputFile), Script.GetAsciiPath(PathManager.PreviewSourceFile));
                }
                if (settings.Deshaker)
                {
                    Script.Replace(Script.GetAsciiPath(settings.DeshakerLog), Script.GetAsciiPath(PathManager.PreviewDeshakerLog));
                }
                settings.CustomScript = Script.Script;
            }
            settings.Save(PathManager.PreviewSettingsFile);
        }
        private static void ApplyDegrain(AviSynthScriptBuilder Script, MediaEncoderSettings settings, ref bool isLsb, ref bool isYV24)
        {
            Script.LoadPluginAvsi("smdegrain.avsi");
            Script.LoadPluginDll("MVTools2.dll");
            Script.LoadPluginDll("MedianBlur2.dll");
            if (settings.DegrainSharp)
            {
                Script.LoadPluginDll("rgtools.dll");
            }
            else
            {
                Script.LoadPluginDll("RemoveGrain.dll");
            }

            if (isYV24)
            {
                if (isLsb)
                {
                    Script.AppendLine(@"Dither_resize16nr(Width, Height/2, kernel=""Spline36"", csp=""YV12"")");
                }
                else
                {
                    Script.AppendLine("ConvertToYV12()");
                }
                isYV24 = false;
            }

            Script.AppendLine("SMDegrain(thsad={0}, prefilter={1}{2}{3})",
                              settings.DegrainStrength * 10,
                              settings.DegrainPrefilter == DegrainPrefilters.SD ? 1 : settings.DegrainPrefilter == DegrainPrefilters.HD ? 2 : 4,
                              settings.DegrainSharp ? ", contrasharp=true" : "",
                              isLsb ? ", lsb_in=true, lsb_out=true" : "");
        }
Beispiel #3
0
        public void PrepareJobFiles(MediaEncoderSettings settings)
        {
            settings.JobIndex = ++JobIndex;
            // Files must be prepared before adding to queue so that user can replace preview files.
            PathManager.DeleteJobFiles(settings.JobIndex);
            File.Delete(PathManager.PreviewScriptFile);
            File.Delete(PathManager.PreviewSettingsFile);
            if (settings.ConvertToAvi)
            {
                PathManager.SafeMove(PathManager.PreviewSourceFile, settings.InputFile);
            }
            if (settings.Deshaker)
            {
                PathManager.SafeMove(PathManager.PreviewDeshakerLog, settings.DeshakerLog);
            }
            settings.Save(settings.SettingsFile);
            AviSynthScriptBuilder Script = new AviSynthScriptBuilder(settings.CustomScript);

            if (Script.IsEmpty)
            {
                Script = MediaEncoderScript.GenerateVideoScript(settings, settings.InputFile, false, true);
            }
            else
            {
                Script.Replace(Script.GetAsciiPath(PathManager.PreviewSourceFile), Script.GetAsciiPath(settings.InputFile));
                Script.Replace(Script.GetAsciiPath(PathManager.PreviewDeshakerLog), Script.GetAsciiPath(settings.DeshakerLog));
            }
            Script.WriteToFile(settings.ScriptFile);
            // if (settings.DeshakerSettings.PrescanAction == PrescanType.Full)
        }
 private static void DitherPost(AviSynthScriptBuilder Script, ref bool isHD, ref bool isYV24, bool furtherProcessing)
 {
     //if (isYV24)
     //    Script.AppendLine(@"ConvertToYUV420(chromaresample=""Spline36"")");
     if (isHD)
     {
         Script.AppendLine("ConvertBits(8, dither={0})", furtherProcessing ? "1" : "0");
     }
     isHD = false;
     //isYV24 = false;
 }
        /// <summary>
        /// Saves the audio output of specified script into a WAV file.
        /// </summary>
        /// <param name="settings">An object containing the encoding settings.</param>
        /// <param name="destination">The WAV file to write.</param>
        /// <param name="options">The options that control the behaviors of the process.</param>
        public static void SaveAudioToWav(MediaEncoderSettings settings, string destination, ProcessStartOptions options)
        {
            string TempFile = settings.TempFile + ".avs";
            AviSynthScriptBuilder Script = new AviSynthScriptBuilder();

            if (settings.VideoAction != VideoAction.Copy)
            {
                // Read source script.
                Script.Script = File.ReadAllText(settings.ScriptFile);
                // Remote MT code.
                Script.RemoveMT();
                Script.AppendLine("Trim(0,0)");
            }
            else
            {
                // Read full video file.
                Script.AddPluginPath();
                if (settings.ConvertToAvi || settings.InputFile.ToLower().EndsWith(".avi"))
                {
                    Script.OpenAvi(settings.InputFile, !string.IsNullOrEmpty(settings.SourceAudioFormat));
                }
                else
                {
                    Script.OpenDirect(settings.InputFile, !string.IsNullOrEmpty(settings.SourceAudioFormat));
                }
                Script.AppendLine("KillVideo()");
            }
            Script.AppendLine();
            // Add audio gain.
            if (settings.AudioGain.HasValue && settings.AudioGain != 0)
            {
                Script.AppendLine("AmplifydB({0})", settings.AudioGain.Value);
            }
            if (settings.ChangeAudioPitch)
            {
                // Change pitch to 432hz.
                Script.LoadPluginDll("TimeStretch.dll");
                Script.AppendLine("ResampleAudio(48000)");
                Script.AppendLine("TimeStretchPlugin(pitch = 100.0 * 0.98181819915771484)");
            }
            // Add TWriteWAV.
            Script.AppendLine();
            Script.LoadPluginDll("TWriteAVI.dll");
            Script.AppendLine(@"TWriteWAV(""{0}"", true)", Script.GetAsciiPath(destination));
            Script.AppendLine("ForceProcessWAV()");

            // Write temp script.
            Script.WriteToFile(TempFile);
            // Execute. It aways returns an error but the file is generated.
            FFmpegProcess Worker = new FFmpegProcess(options);

            Worker.RunAvisynth(TempFile);
            File.Delete(TempFile);
        }
 public void GenerateScript(MediaEncoderSettings settings, bool preview, bool multiThreaded) {
     AviSynthScriptBuilder Script = new AviSynthScriptBuilder(settings.CustomScript);
     if (Script.IsEmpty)
         Script = MediaEncoderScript.GenerateVideoScript(settings, GetPreviewSourceFile(settings), preview, multiThreaded);
     else if (preview) {
         Script.RemoveMT();
         Script.AppendLine(@"ConvertToRGB32(matrix=""Rec709"")");
     } else if (!multiThreaded)
         Script.RemoveMT();
     Script.WriteToFile(PathManager.PreviewScriptFile);
     settings.Save(PathManager.PreviewSettingsFile);
 }
Beispiel #7
0
        /// <summary>
        /// Gets an AviSynth clip information by running a script that outputs the frame count to a file.
        /// </summary>
        /// <param name="source">The AviSynth script to get information for.</param>
        /// <param name="silent">If true, the x264 window will be hidden.</param>
        /// <returns>The clip information.</returns>
        public static ClipInfo GetClipInfo(MediaEncoderSettings settings, string scriptFile, bool silent)
        {
            string TempScript = settings.TempFile + ".avs";
            string TempResult = settings.TempFile + ".txt";
            string TempOut    = settings.TempFile + ".y4m";

            // Read source script and remove MT. Also remove Deshaker if present.
            string FileContent = File.ReadAllText(scriptFile);

            FileContent.Replace(Environment.NewLine + "Deshaker", Environment.NewLine + "#Deshaker");
            AviSynthScriptBuilder Script = new AviSynthScriptBuilder(FileContent);

            Script.RemoveMT();
            //Script.DitherOut(false);

            // Get frame count.
            Script.AppendLine();
            Script.AppendLine(@"WriteFileStart(""{0}"", ""FrameRate""{1}""Framecount"")", TempResult, @", """""" "","" """""", ");
            Script.AppendLine("Trim(0,-1)");
            Script.WriteToFile(TempScript);

            // Run script.
            Run(@"Encoder\avs2yuv.exe", String.Format(@"""{0}"" -o {1}", TempScript, TempOut), true);

            // Read frame count
            ClipInfo Result = null;

            if (File.Exists(TempResult))
            {
                string   FileString = File.ReadAllText(TempResult);
                string[] FileValues = FileString.Split(',');
                Result = new ClipInfo();
                try {
                    Result.FrameRate  = float.Parse(FileValues[0], CultureInfo.InvariantCulture);
                    Result.FrameCount = int.Parse(FileValues[1]);
                }
                catch {
                    Result = null;
                }
            }

            // Delete temp files.
            File.Delete(TempScript);
            File.Delete(TempResult);
            File.Delete(TempOut); // Dummy file that received avs2yuv output.

            return(Result);
        }
Beispiel #8
0
        /// <summary>
        /// Returns whether the GPU supports the latest version of KNLMeans with OpenCL 1.2
        /// </summary>
        /// <param name="supports11">If true, it will instead test whether the GPU supports OpenCL 1.1</param>
        /// <returns>True if OpenCL is supported.</returns>
        private static bool GpuSupportsOpenCL(bool version12)
        {
            string TempScript = Settings.TempFilesPath + "Temp.avs";
            string TempResult = Settings.TempFilesPath + "Temp.txt";
            string TempOut    = Settings.TempFilesPath + "Temp.y4m";

            AviSynthScriptBuilder Script = new AviSynthScriptBuilder();

            Script.AddPluginPath();
            Script.LoadPluginDll(string.Format("KNLMeansCL{0}.dll", version12 ? "" : "-6.11"));
            Script.AppendLine(@"colorbars(pixel_type = ""yv12"").killaudio().trim(1, 1)");
            Script.AppendLine("Result = true");
            Script.AppendLine("try {");
            Script.AppendLine(@"KNLMeansCL(device_type=""GPU"")");
            Script.AppendLine("} catch(error_msg) {");
            Script.AppendLine("Result = false");
            Script.AppendLine("}");
            Script.AppendLine(@"WriteFileStart(""{0}"", string(Result))", TempResult);
            Script.WriteToFile(TempScript);

            // Run script.
            FfmpegBusiness.Run(@"Encoder\avs2yuv.exe", String.Format(@"""{0}"" -o ""{1}""", TempScript, TempOut), true);

            // Read frame count
            bool Result = false;

            if (File.Exists(TempResult))
            {
                string FileString = File.ReadAllText(TempResult);
                try {
                    Result = bool.Parse(FileString.TrimEnd());
                }
                catch {
                    Result = false;
                }
            }

            // Delete temp files.
            File.Delete(TempScript);
            File.Delete(TempResult);
            File.Delete(TempOut); // Dummy file that received avs2yuv output.

            return(Result);
        }
        private static void ApplyInterFrame(AviSynthScriptBuilder Script, MediaEncoderSettings settings, int CPU)
        {
            Script.LoadPluginDll("FrameRateConverter.dll");
            Script.LoadPluginAvsi("FrameRateConverter.avsi");
            Script.LoadPluginDll("MaskTools2.dll");
            Script.LoadPluginDll("MvTools2.dll");
            string Prefilter = "";

            if (!settings.Denoise)
            {
                Script.LoadPluginDll("RgTools.dll");
                Prefilter = ", Prefilter=RemoveGrain(21)";
            }
            if (settings.IncreaseFrameRateValue == FrameRateModeEnum.Double)
            {
                Script.AppendLine(@"FrameRateConverter(FrameDouble=true){0}", Prefilter);
            }
            else
            {
                int NewNum = 0;
                int NewDen = 0;
                if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps30)
                {
                    NewNum = 30; // 30000;
                    NewDen = 1;  //  1001;
                }
                else if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps60)
                {
                    NewNum = 60; // 60000;
                    NewDen = 1;  // 1001;
                }
                else if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps120)
                {
                    NewNum = 120; // 120000;
                    NewDen = 1;   // 1001;
                }
                Script.AppendLine(@"FrameRateConverter(NewNum={0}, NewDen={1}, Preset=""{2}""{3})", NewNum, NewDen, settings.IncreaseFrameRatePreset, Prefilter);
            }
        }
        private static void ApplyDeshaker(AviSynthScriptBuilder Script, MediaEncoderSettings settings, ref bool isLsb, ref bool isYV24, bool multiProcess)
        {
            settings.DeshakerSettings.LogFile = Script.GetAsciiPath(settings.DeshakerLog);
            settings.DeshakerSettings.Pass    = 2;
            Script.LoadPluginDll(@"VDubFilter.dll");

            Script.AppendLine(@"LoadVirtualDubPlugin(P+""deshaker.vdf"", ""deshaker"", preroll=0)");
            Script.AppendLine(@"ConvertToRGB32(matrix=""Rec709"")");
            if (multiProcess)
            {
                Script.AppendLine("### prefetch: 3, 3"); // Keep 3 frames before and after for temporal filters.
                Script.AppendLine("### ###");            // MP_Pipeline starts new process here
            }
            Script.AppendLine(@"deshaker(""{0}"")", settings.DeshakerSettings.ToString());
            Script.AppendLine(@"ConvertToYV12(matrix=""Rec709"")");
            if (multiProcess)
            {
                Script.AppendLine("### prefetch: {0}, {1}", settings.DeshakerSettings.FillBordersWithFutureFrames ? settings.DeshakerSettings.FillBordersWithFutureFramesCount : 0, settings.DeshakerSettings.FillBordersWithPreviousFrames ? settings.DeshakerSettings.FillBordersWithPreviousFramesCount : 0);
                Script.AppendLine("### ###"); // MP_Pipeline starts another here
            }
            isLsb  = false;
            isYV24 = false;
        }
        /// <summary>
        /// Generates a script for Deshaker prescan. This is a much simplified version of the full script that will execute faster.
        /// </summary>
        public static string GenerateDeshakerScript(MediaEncoderSettings settings, string inputFile, int segment, long frameStart, long frameEnd)
        {
            bool MultiProcesses = false;

            // Calculate encoding and final frame rates.
            double ChangeSpeedValue = settings.ChangeSpeed ? (double)settings.ChangeSpeedValue / 100 : 1;
            double FrameRateBefore  = settings.SourceFrameRate.Value * ChangeSpeedValue;

            // Generate video script.
            AviSynthScriptBuilder Script = new AviSynthScriptBuilder();

            Script.AddPluginPath();
            Script.LoadPluginDll("VDubFilter.dll");
            Script.AppendLine(@"LoadVirtualDubPlugin(P+""deshaker.vdf"", ""deshaker"", preroll=0)");
            if (settings.ConvertToAvi || inputFile.ToLower().EndsWith(".avi"))
            {
                Script.OpenAvi(inputFile, false);
            }
            else
            {
                Script.OpenDirect(inputFile, false);
            }
            if (FrameRateBefore != settings.SourceFrameRate)
            {
                Script.AppendLine(CultureInfo.InvariantCulture, "AssumeFPS({0}, true)", FrameRateBefore);
            }
            if (settings.Trim)
            {
                Script.AppendLine("Trim({0}, {1})",
                                  (settings.TrimStart ?? 0) > 0 ? (int)(settings.TrimStart.Value * settings.SourceFrameRate.Value) : 0,
                                  (settings.TrimEnd ?? 0) > 0 ? (int)(settings.TrimEnd.Value * settings.SourceFrameRate.Value) : 0);
            }
            if (settings.CropSource.HasValue)
            {
                Script.AppendLine("Crop({0}, {1}, -{2}, -{3})", settings.CropSource.Left, settings.CropSource.Top, settings.CropSource.Right, settings.CropSource.Bottom);
            }

            // Generate script for a segment.
            if (frameStart > 0 || frameEnd > 0)
            {
                Script.AppendLine("Trim({0}, {1})", frameStart, frameEnd);
            }

            // Resize to the dimention deshaker will run at.
            if (settings.FrameDouble == 1)
            {
                int FinalWidth  = settings.OutputWidth.Value + settings.CropAfter.Left + settings.CropAfter.Right;
                int FinalHeight = settings.OutputHeight + settings.CropAfter.Top + settings.CropAfter.Bottom;
                Script.AppendLine("BicubicResize({0}, {1})", FinalWidth, FinalHeight);
            }
            else if (settings.FrameDouble > 1)
            {
                Script.AppendLine("BicubicResize(Width*2, Height*2)");
            }

            // Deshaker requires RGB input.
            Script.AppendLine(@"ConvertToRGB32(matrix=""{0}"")",
                              settings.SourceColorMatrix == ColorMatrix.Rec601 ? "Rec601" : settings.SourceColorMatrix == ColorMatrix.Pc709 ? "Pc709" : settings.SourceColorMatrix == ColorMatrix.Pc601 ? "Pc601" : "Rec709");

            // Generate log file
            Script.AppendLine(@"deshaker(""{0}"")", settings.DeshakerSettings.ToString(segment));

            // FFMPEG will generate an AVI file; make it 8x8 to minimize processing.
            Script.AppendLine("ConvertToYV12()");
            Script.AppendLine("PointResize(64,64)");
            if (MultiProcesses)
            {
                Script.AppendLine("### prefetch: 0, 0");
                Script.AppendLine("### branch: 2");
                Script.AppendLine("### ###");
                Script.ConvertToMultiProcesses(settings.SourceFrameRate.Value);
            }

            return(Script.Script);
        }
        public static AviSynthScriptBuilder GenerateVideoScript(MediaEncoderSettings settings, string inputFile, bool preview, bool multiThreaded)
        {
            // int CPU = multiThreaded ? Environment.ProcessorCount : 1;
            int CPU = multiThreaded ? settings.Threads : 1;

            if (CPU <= 1)
            {
                multiThreaded = false;
            }
            bool RunMultiProcesses = false;

            if (settings.Deshaker && multiThreaded)
            {
                RunMultiProcesses = true;  // Run through MP_Pipeline
                multiThreaded     = false; // Deshaker doesn't work with MT
                CPU = 1;
            }
            //if (settings.Threads > 0) {
            //    multiThreaded = false;
            //    CPU = 1;
            //}

            settings.CalculateSize();

            // Calculate encoding and final frame rates.
            double ChangeSpeedValue = (settings.ChangeSpeed && settings.CanAlterAudio) ? (double)settings.ChangeSpeedValue / 100 : 1;
            double FrameRateBefore  = settings.SourceFrameRate.Value * ChangeSpeedValue;

            // Generate video script.
            AviSynthScriptBuilder Script = new AviSynthScriptBuilder();
            bool IsYV24 = false;

            Script.AppendLine(); // After clean-up, this adds a line after LoadPlugin commands.
            Script.AddPluginPath();
            if (multiThreaded)
            {
                Script.LoadPluginAvsi("AviSynthMT.avsi");
            }
            if (settings.ConvertToAvi || inputFile.ToLower().EndsWith(".avi"))
            {
                Script.OpenAvi(inputFile, !string.IsNullOrEmpty(settings.SourceAudioFormat));
            }
            else
            {
                Script.OpenDirect(inputFile, !string.IsNullOrEmpty(settings.SourceAudioFormat));
            }
            if (FrameRateBefore != settings.SourceFrameRate)
            {
                Script.AppendLine(CultureInfo.InvariantCulture, "AssumeFPS({0}, true)", FrameRateBefore);
            }
            if (settings.Trim && settings.CanAlterAudio)
            {
                Script.AppendLine("Trim({0}, {1})",
                                  (settings.TrimStart ?? 0) > 0 ? (int)(settings.TrimStart.Value * settings.SourceFrameRate.Value) : 0,
                                  (settings.TrimEnd ?? 0) > 0 && !preview ? (int)(settings.TrimEnd.Value * settings.SourceFrameRate.Value) : 0);
            }

            if (settings.Denoise)
            {
                //Script.LoadPluginDll("MvTools2.dll");
                //Script.LoadPluginDll("MaskTools2.dll");
                //Script.LoadPluginDll("FFT3DFilter.dll");
                //Script.LoadPluginDll("ModPlus.dll");
                //Script.LoadPluginDll("RgTools.dll");
                //Script.LoadPluginDll("DCTFilter.dll");
                //Script.LoadPluginAvsi("mClean.avsi");
                //Script.AppendLine("mClean(rn={0}{1})", 10, IsHD ? ", outbits=16" : "");
                Script.AppendLine(@"MCTemporalDenoise(settings=""{0}""{1})", "medium", settings.Deblock ? ", deblock=true" : "");
            }
            else if (settings.Deblock)
            {
                Script.LoadPluginDll("MaskTools2.dll");
                Script.LoadPluginDll("DCTFilter.dll");
                Script.LoadPluginDll("deblock.dll");
                Script.LoadPluginAvsi("Deblock_QED.avsi");
                Script.AppendLine("Deblock_QED()");
            }

            if (settings.CropSource.HasValue)
            {
                Script.AppendLine("Crop({0}, {1}, -{2}, -{3})", settings.CropSource.Left, settings.CropSource.Top, settings.CropSource.Right, settings.CropSource.Bottom);
            }

            // If possible, KNLMeans will output 16-bit frames before upscaling.
            bool IsHD            = (settings.Dering || settings.Deblock || settings.Degrain || settings.SourceColorMatrix != ColorMatrix.Rec709 || (settings.FrameDouble > 0 && (settings.SuperRes || settings.UpscaleMethod == UpscaleMethods.SuperXbr)));
            bool IsColorMatrixHD = IsHD;
            bool IsChromaFixed   = settings.SourceChromaPlacement == ChromaPlacement.MPEG2;

            if (IsHD)
            {
                //if (!settings.Denoise)
                Script.AppendLine("ConvertBits(16)");
                if (settings.SourceColorMatrix != ColorMatrix.Rec709)
                {
                    Script.AppendLine("[ColorMatrixShader]"); // Placeholder that will be replaced after generating the rest.
                }
            }

            if (settings.FixDoubleFrames)
            {
                Script.LoadPluginDll("FrameRateConverter.dll");
                Script.LoadPluginAvsi("FrameRateConverter.avsi");
                Script.LoadPluginDll("MaskTools2.dll");
                Script.LoadPluginDll("MvTools2.dll");
                Script.AppendLine("InterpolateDoubles(.1)");
            }

            if (settings.Dering)
            {
                Script.LoadPluginAvsi("HQDeringmod.avsi");
                Script.LoadPluginDll("MedianBlur2.dll");
                Script.LoadPluginDll("dfttest.dll");
                Script.LoadPluginDll("RgTools.dll");
                Script.LoadPluginDll("SmoothAdjust.dll");
                Script.AppendLine("HQDeringmod({0})", IsHD ? "lsb_in=true, lsb=true" : "");
            }

            if (settings.Degrain)
            {
                ApplyDegrain(Script, settings, ref IsHD, ref IsYV24);
            }
            if (settings.Deshaker)
            {
                ApplyDeshaker(Script, settings, ref IsHD, ref IsYV24, RunMultiProcesses);
            }

            if (settings.FrameDouble > 0)
            {
                Script.AppendLine(@"ConvertToYUV444({0})",
                                  !IsChromaFixed ? string.Format(@"ChromaInPlacement=""{0}""", settings.SourceChromaPlacement.ToString()) : "");
                IsYV24        = true;
                IsChromaFixed = true;
            }

            string FinalSize = string.Format("fWidth={0}, fHeight={1}",
                                             settings.OutputWidth + settings.CropAfter.Left + settings.CropAfter.Right,
                                             settings.OutputHeight + settings.CropAfter.Top + settings.CropAfter.Bottom);
            string FinalResize = FinalSize;

            if (settings.DownscaleMethod == DownscaleMethods.SSim)
            {
                FinalResize += string.Format(@", fKernel=""SSim"", fB={0}{1}",
                                             settings.SSimStrength / 100, settings.SSimSoft ? ", fC=1" : "");
            }
            else // DownscaleMethod == Bicubic
            {
                FinalResize += string.Format(@", fKernel=""Bicubic"", fB=0, fC=.75");
            }

            if (settings.FrameDouble > 0)
            {
                if (settings.UpscaleMethod == UpscaleMethods.NNedi3)
                {
                    bool IsLastDouble = false;
                    DitherPost(Script, ref IsHD, ref IsYV24, true);

                    Script.LoadPluginDll("nnedi3.dll");
                    Script.LoadPluginAvsi("edi_rpow2.avsi");
                    Script.LoadPluginAvsi("ResizeX.avsi");

                    for (int i = 0; i < settings.FrameDouble; i++)
                    {
                        IsLastDouble = i == settings.FrameDouble - 1;
                        string DoubleScript = string.Format("edi_rpow2(2, nns=4, {0}, Threads=2)",
                                                            IsLastDouble && settings.DownscaleMethod == DownscaleMethods.Bicubic ? @"cshift=""Bicubic"", a1=0, a2=.75, " + FinalSize : @"cshift=""Spline16Resize""");
                        if (settings.SuperRes)
                        {
                            Script.AppendLine(CultureInfo.InvariantCulture, @"SuperRes({0}, {1}, {2}, """"""{3}""""""{4}{5}{6})",
                                              settings.SuperRes3Passes ? (i == 0 && settings.FrameDouble > 1 ? 5 : 3) : 2,
                                              settings.SuperResStrength / 100f, settings.SuperResSoftness / 100f, DoubleScript,
                                              i == 0 ? GetMatrixIn(settings) : "",
                                              IsLastDouble && settings.DownscaleMethod == DownscaleMethods.SSim ? ", " + FinalResize : "",
                                              multiThreaded ? "" : ", Engines=1");
                        }
                        else
                        {
                            Script.AppendLine(DoubleScript);
                            if (IsLastDouble && settings.DownscaleMethod == DownscaleMethods.SSim)
                            {
                                Script.AppendLine("ResizeShader({0}{1})",
                                                  FinalResize.Replace("fWidth=", "").Replace("fHeight=", "").Replace(" f", " "), // Use same string as FinalResize but remove 'f' parameter sufix.
                                                  GetMatrixIn(settings));
                            }
                        }
                    }
                }
                else     // UpscaleMethod == SuperXBR
                {
                    if (settings.SuperRes)
                    {
                        Script.AppendLine(CultureInfo.InvariantCulture, @"SuperResXBR({0}, {1}, {2}{3}, XbrStr={4}, XbrSharp={5}{6}, {7}, FormatOut=""YV12""{8})",
                                          settings.SuperRes3Passes ? (settings.IncreaseFrameRate ? 5 : 3) : 2,
                                          settings.SuperResStrength / 100f, settings.SuperResSoftness / 100f,
                                          settings.FrameDouble > 1 ? ", Factor=" + (1 << settings.FrameDouble).ToString() : "",
                                          settings.SuperXbrStrength / 10f, settings.SuperXbrSharpness / 10f,
                                          GetMatrixIn(settings),
                                          FinalResize,
                                          multiThreaded ? "" : ", Engines=1");
                    }
                    else
                    {
                        Script.AppendLine(@"SuperXBR(Str={0}, Sharp={1}{2}{3}, {4}, FormatOut=""YV12""{5})",
                                          settings.SuperXbrStrength / 10f, settings.SuperXbrSharpness / 10f,
                                          settings.FrameDouble > 1 ? ", Factor=" + (1 << settings.FrameDouble).ToString() : "",
                                          GetMatrixIn(settings),
                                          FinalResize,
                                          multiThreaded ? "" : ", Engines=1");
                    }
                    IsHD   = false;
                    IsYV24 = false;
                }
            }

            if (settings.DownscaleMethod != DownscaleMethods.SSim)
            {
                DitherPost(Script, ref IsHD, ref IsYV24, settings.IncreaseFrameRate);
            }

            string[] ShaderCommands = new string[] { "SuperRes", "SuperXBR", "SuperResXBR", "ResizeShader" };
            if (settings.CropAfter.HasValue || settings.FrameDouble == 0)
            {
                if (settings.CropAfter.HasValue || settings.SourceAspectRatio != 1 || settings.OutputWidth != settings.SourceWidth || settings.OutputHeight != settings.OutputHeight)
                {
                    if (settings.DownscaleMethod == DownscaleMethods.SSim && settings.FrameDouble == 0)
                    {
                        Script.AppendLine("ResizeShader({0}{1})",
                                          FinalResize.Replace("fWidth=", "").Replace("fHeight=", "").Replace(" f", " "), // Use same string as FinalResize but remove 'f' parameter sufix.
                                          GetMatrixIn(settings));
                    }
                    DitherPost(Script, ref IsHD, ref IsYV24, false);

                    if (settings.CropAfter.HasValue || settings.DownscaleMethod == DownscaleMethods.Bicubic)
                    {
                        Script.LoadPluginAvsi("ResizeX.avsi");
                        bool   ApplyResize = settings.FrameDouble == 0 || !Script.ContainsAny(ShaderCommands);
                        string CropFormat  = "ResizeX";
                        CropFormat += settings.CropAfter.HasValue ? "({0}, {1}, {2}, {3}, -{4}, -{5}{6})" : "({0}, {1}{6})";
                        Script.AppendLine(CropFormat, settings.OutputWidth, settings.OutputHeight,
                                          settings.CropAfter.Left, settings.CropAfter.Top, settings.CropAfter.Right, settings.CropAfter.Bottom,
                                          ApplyResize ? @", kernel=""Bicubic"", a1=0, a2=.75" : "");
                    }
                }
            }

            // Use ColorMatrixShader only if it wasn't already applied through any other shader.
            if (Script.ContainsAny(ShaderCommands))
            {
                // ColorMatrix was applied though another shader.
                Script.Replace("[ColorMatrixShader]" + Environment.NewLine, "");
                Script.LoadPluginDll("Shader.dll");
                Script.LoadPluginAvsi("Shader.avsi");
            }
            else
            {
                string ColorMatrixScript = "";
                // Apply color matrix
                if (settings.SourceColorMatrix == ColorMatrix.Pc709)
                {
                    Script.LoadPluginDll("SmoothAdjust.dll");
                    ColorMatrixScript = string.Format(@"ColorYUV(levels=""PC->TV""");
                }
                else if (settings.SourceColorMatrix != ColorMatrix.Rec709)
                {
                    Script.LoadPluginDll("Shader.dll");
                    Script.LoadPluginAvsi("Shader.avsi");
                    ColorMatrixScript = string.Format(@"ResizeShader(Kernel=""ColorMatrix""{0})", GetMatrixIn(settings));
                }
                Script.Replace("[ColorMatrixShader]" + Environment.NewLine, ColorMatrixScript + Environment.NewLine);
            }

            if (settings.IncreaseFrameRate)
            {
                if (IsYV24)
                {
                    Script.AppendLine(@"ConvertToYUV420()");
                    IsYV24 = false;
                }
                DitherPost(Script, ref IsHD, ref IsYV24, true);
                ApplyInterFrame(Script, settings, CPU);
            }

            if (preview)
            {
                if (settings.Crop)
                {
                    Script.AppendLine("AddBorders(2, 2, 2, 2, $FFFFFF)");
                }
                Script.AppendLine(@"ConvertToRGB32(matrix=""Rec709"")");
            }
            if (multiThreaded)
            {
                Script.AppendLine("Prefetch({0})", CPU);
            }

            if (RunMultiProcesses)
            {
                Script.ConvertToMultiProcesses(settings.SourceFrameRate.Value);
            }
            else
            {
                Script.Cleanup();
            }

            return(Script);
        }
        /// <summary>
        /// Calculates auto-crop coordinates for specified video script.
        /// </summary>
        /// <param name="filePath">The script to analyze.</param>
        /// <param name="sourceWidth">The width of the source video.</param>
        /// <param name="sourceHeight">The height of the source video.</param>
        /// <param name="options">The options that control the behaviors of the process.</param>
        /// <returns>The auto-crop coordinates.</returns>
        public static Rect GetAutoCropRect(string filePath, int sourceWidth, int sourceHeight, ProcessStartOptions options)
        {
            string TempScript = PathManager.GetTempFile(".avs");
            string TempResult = Path.ChangeExtension(TempScript, ".txt");

            // Create script to get auto-crop coordinates
            AviSynthScriptBuilder Script = new AviSynthScriptBuilder();

            Script.AddPluginPath();
            Script.OpenDirect(filePath, false);
            Script.LoadPluginDll("RoboCrop26.dll");
            Script.AppendLine(@"RoboCrop(LogFn=""{0}"")", Script.GetAsciiPath(TempResult));
            Script.AppendLine("Trim(0,-1)");
            Script.WriteToFile(TempScript);

            // Run script.
            FFmpegProcess Worker = new FFmpegProcess(options);

            Worker.RunAvisynth(TempScript);

            // Read auto crop coordinates
            Rect Result = new Rect();

            if (File.Exists(TempResult))
            {
                string[] Values = File.ReadAllText(TempResult).Split(' ');
                if (Values.Length >= 13)
                {
                    Result.Left   = Math.Max(int.Parse(Values[10]), 0);
                    Result.Top    = Math.Max(int.Parse(Values[11]), 0);
                    Result.Right  = Math.Max(sourceWidth - int.Parse(Values[12]), 0);
                    Result.Bottom = Math.Max(sourceHeight - int.Parse(Values[13]), 0);
                    // Make result conservative, we have to visually see a line of black border to know the right dimensions.
                    if (Result.Left > 0)
                    {
                        Result.Left--;
                    }
                    if (Result.Top > 0)
                    {
                        Result.Top--;
                    }
                    if (Result.Right > 0)
                    {
                        Result.Right--;
                    }
                    if (Result.Bottom > 0)
                    {
                        Result.Bottom--;
                    }
                }
            }

            // Delete temp files.
            Exception LastError = null;

            for (int i = 0; i < 10; i++)
            {
                try {
                    File.Delete(TempScript);
                    File.Delete(TempResult);
                    break;
                } catch (Exception e) {
                    LastError = e;
                    System.Threading.Thread.Sleep(500);
                }
            }
            if (LastError != null)
            {
                throw LastError;
            }

            return(Result);
        }
Beispiel #14
0
        public static Rect GetAutoCropRect(MediaEncoderSettings settings, bool silent)
        {
            string TempScript = settings.TempFile + ".avs";
            string TempResult = settings.TempFile + ".txt";
            string TempOut    = settings.TempFile + ".y4m";

            // Create script to get auto-crop coordinates
            AviSynthScriptBuilder Script = new AviSynthScriptBuilder();

            Script.AddPluginPath();
            Script.OpenDirect(settings.FilePath, false);
            Script.LoadPluginDll("RoboCrop26.dll");
            Script.AppendLine(@"RoboCrop(LogFn=""{0}"")", Script.GetAsciiPath(TempResult));
            Script.AppendLine("Trim(0,-1)");
            Script.WriteToFile(TempScript);

            // Run script.
            Run(@"Encoder\avs2yuv.exe", String.Format(@"""{0}"" -o ""{1}""", TempScript, TempOut), true);

            // Read auto crop coordinates
            Rect Result = new Rect();

            if (File.Exists(TempResult))
            {
                string[] Values = File.ReadAllText(TempResult).Split(' ');
                if (Values.Length >= 13)
                {
                    Result.Left   = int.Parse(Values[10]);
                    Result.Top    = int.Parse(Values[11]);
                    Result.Right  = settings.SourceWidth.Value - int.Parse(Values[12]);
                    Result.Bottom = settings.SourceHeight.Value - int.Parse(Values[13]);
                    // Make result conservative, we have to visually see a line of black border to know the right dimensions.
                    if (Result.Left > 0)
                    {
                        Result.Left--;
                    }
                    if (Result.Top > 0)
                    {
                        Result.Top--;
                    }
                    if (Result.Right > 0)
                    {
                        Result.Right--;
                    }
                    if (Result.Bottom > 0)
                    {
                        Result.Bottom--;
                    }
                }
            }

            // Delete temp files.
            Exception LastError = null;

            for (int i = 0; i < 10; i++)
            {
                try {
                    File.Delete(TempScript);
                    File.Delete(TempResult);
                    File.Delete(TempOut); // Dummy file that received avs2yuv output.
                    break;
                }
                catch (Exception e) {
                    LastError = e;
                    System.Threading.Thread.Sleep(500);
                }
            }
            if (LastError != null)
            {
                throw LastError;
            }

            return(Result);
        }