/// <summary>
        /// Returns the code for the MatrixIn argument based on SourceColorMatrix.
        /// </summary>
        private static string GetMatrixIn(MediaEncoderSettings settings)
        {
            string Result = null;

            if (settings.SourceColorMatrix == ColorMatrix.Rec601)
            {
                Result = "Rec601";
            }
            else if (settings.SourceColorMatrix == ColorMatrix.Pc601)
            {
                Result = "Pc601";
            }
            else if (settings.SourceColorMatrix == ColorMatrix.Pc709)
            {
                Result = "Pc709";
            }
            if (Result != null)
            {
                return(string.Format(@", MatrixIn=""{0}""", Result));
            }
            else
            {
                return("");
            }
        }
        private EncodingCompletedEventArgs FinalizeEncoding(MediaEncoderSettings settings, DateTime? startTime) {
            settings.ResumePos = -1;
            string VideoFile = settings.VideoAction == VideoAction.Discard ? null : settings.VideoAction == VideoAction.Copy ? settings.FilePath : settings.OutputFile;

            if (!File.Exists(settings.OutputFile) && settings.VideoAction != VideoAction.Copy) {
                // Merge segments.
                settings.CompletionStatus = MergeSegments(settings, VideoFile);
                if (settings.CompletionStatus != CompletionStatus.Success)
                    return null;
            }

            if (!File.Exists(settings.FinalFile)) {
                // Muxe video with audio.
                string AudioFile = settings.AudioAction == AudioActions.Discard ? null : settings.AudioAction == AudioActions.Copy ? settings.FilePath : settings.AudioFile;
                if (AudioFile == null)
                    File.Move(VideoFile, settings.FinalFile);
                else if (VideoFile == null)
                    File.Move(AudioFile, settings.FinalFile);
                else
                    settings.CompletionStatus = MediaMuxer.Muxe(VideoFile, AudioFile, settings.FinalFile, new ProcessStartOptions(settings.JobIndex, "Muxing Audio and Video", false));
                if (settings.CompletionStatus != CompletionStatus.Success)
                    return null;

            }

            return GetEncodingResults(settings, settings.FinalFile, startTime);
        }
        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" : "");
        }
예제 #4
0
        public static float?GetPixelAspectRatio(MediaEncoderSettings settings)
        {
            string ConsoleOut = RunToString("Encoder\\ffmpeg.exe", string.Format(@"-i ""{0}""", settings.FilePath));
            int    PosStart   = ConsoleOut.IndexOf("[SAR ") + 5;
            int    PosEnd     = ConsoleOut.IndexOf(" DAR ", PosStart);

            if (PosStart < 0 || PosEnd < 0)
            {
                return(null);
            }
            string SARText = ConsoleOut.Substring(PosStart, PosEnd - PosStart);

            string[] SAR = SARText.Split(':');
            if (SAR.Length != 2)
            {
                return(null);
            }
            try {
                float Result = (float)Math.Round((decimal)int.Parse(SAR[0]) / int.Parse(SAR[1]), 3);
                return(Result);
            }
            catch {
                return(null);
            }
        }
예제 #5
0
        public static bool RunDeshakerPass(MediaEncoderSettings settings, ExecutingProcessHandler callback)
        {
            string TempOut = settings.DeshakerLog + ".y4m";
            string Args    = string.Format(@"""{0}"" -o - ""{1}""", settings.DeshakerScript, TempOut);
            bool   Result  = Run(@"Encoder\avs2yuv.exe", Args, true, ProcessPriorityClass.Normal, callback);

            File.Delete(TempOut);
            return(Result);
        }
 public void GenerateScript(MediaEncoderSettings settings, bool preview, bool multiThreaded) {
     string Script = settings.CustomScript;
     if (string.IsNullOrEmpty(Script))
         Script = GetVideoScript(settings, GetPreviewSourceFile(settings), preview, multiThreaded);
     else if (preview)
         Script = ConvertScriptForPreview(Script);
     WriteFile(Script, PreviewScriptFile);
     SaveSettingsFile(settings, PreviewSettingsFile);
 }
        /// <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 bool PauseEncoding() {
     if (IsEncoding) {
         IsEncoding = false;
         MediaEncoderSettings Job = ProcessingQueue.FirstOrDefault();
         if (Job != null) {
             Job.CompletionStatus = CompletionStatus.Cancelled;
             FFmpegConfig.UserInterfaceManager.Stop(Job.JobIndex);
             return true;
         }
     }
     return false;
 }
 public void GenerateScript(MediaEncoderSettings settings, bool preview, bool multiThreaded) {
     AviSynthScriptBuilder Script = new AviSynthScriptBuilder(settings.CustomScript);
     if (Script.IsEmpty)
         Script = GenerateVideoScript(settings, GetPreviewSourceFile(settings), preview, multiThreaded);
     else if (preview) {
         Script.RemoveMT();
         Script.AppendLine(@"ConvertToRGB32(matrix=""Rec709"")");
     } else if (!multiThreaded)
         Script.RemoveMT();
     Script.WriteToFile(PreviewScriptFile);
     SaveSettingsFile(settings, PreviewSettingsFile);
 }
 /// <summary>
 /// Prepares the files of an existing job.
 /// </summary>
 /// <returns>A MediaEncoderSegments object containing the segments analysis.</returns>
 public MediaEncoderSegments PrepareExistingJob(MediaEncoderSettings settings) {
     settings.ResumePos = 0;
     settings.CompletionStatus = CompletionStatus.Success;
     if (File.Exists(settings.FinalFile)) {
         // Merging was completed.
         return null;
     } else {
         MediaEncoderSegments SegBusiness = new MediaEncoderSegments();
         SegBusiness.Analyze(settings);
         return SegBusiness;
     }
 }
 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);
 }
        private CompletionStatus GenerateDeshakerLogSegment(MediaEncoderSettings settings, string inputFile, int segment, long jobStart, long frameStart, long frameEnd, ProcessStartOptions jobOptions) {
            // Write Deshaker Pass 1 script to file.
            string Script = MediaEncoderScript.GenerateDeshakerScript(settings, inputFile, segment, frameStart, frameEnd);
            File.WriteAllText(settings.DeshakerScript, Script);

            // Run pass.
            jobOptions.IsMainTask = true;
            jobOptions.Title = "Running Deshaker Prescan";
            jobOptions.ResumePos = frameStart - jobStart;
            CompletionStatus Result = MediaEncoder.ConvertToAvi(settings.DeshakerScript, settings.DeshakerTempOut, false, jobOptions);
            File.Delete(settings.DeshakerScript);
            File.Delete(settings.DeshakerTempOut);
            return Result;
        }
 /// <summary>
 /// Auto-load Preview file if encoded was unexpectedly closed.
 /// </summary>
 /// <returns>The previous preview encoding settings.</returns>
 public async Task<MediaEncoderSettings> AutoLoadPreviewFileAsync() {
     if (File.Exists(PathManager.PreviewSettingsFile)) {
         MediaEncoderSettings settings = MediaEncoderSettings.Load(PathManager.PreviewSettingsFile);
         if (!File.Exists(PathManager.PreviewSourceFile) && File.Exists(settings.FilePath)) {
             double? SourceFps = settings.SourceFrameRate; // Keep FPS in case it cannot be read from the file.
             await PreparePreviewFile(settings, false, false);
             if (!settings.SourceFrameRate.HasValue)
                 settings.SourceFrameRate = SourceFps;
         }
         settings.JobIndex = -1;
         return settings;
     }
     return null;
 }
        /// <summary>
        /// Encodes specified audio file according to settings. The script file must already be written.
        /// </summary>
        /// <param name="settings">An object containing the encoding settings.</param>
        /// <returns>The endoding completion status..</returns>
        public static CompletionStatus EncodeAudio(MediaEncoderSettings settings)
        {
            CompletionStatus    Result  = CompletionStatus.Success;
            string              WavFile = PathManager.GetAudioFile(settings.JobIndex, AudioActions.Wav);
            ProcessStartOptions Options = new ProcessStartOptions(settings.JobIndex, "Exporting Audio", false).TrackProcess(settings);

            if (!File.Exists(WavFile))
            {
                EncoderBusiness.SaveAudioToWav(settings, WavFile, Options);
                if (settings.CompletionStatus == CompletionStatus.Cancelled)
                {
                    File.Delete(WavFile);
                    return(CompletionStatus.Cancelled);
                }
                if (!File.Exists(WavFile))
                {
                    settings.Cancel();
                    return(CompletionStatus.Error);
                }
            }

            string DestFile = PathManager.GetAudioFile(settings.JobIndex, settings.AudioAction);

            if (!File.Exists(DestFile))
            {
                Options.Title = "Encoding Audio";
                if (settings.AudioAction == AudioActions.Opus)
                {
                    string        Args   = string.Format(@"--bitrate {0} ""{1}"" ""{2}""", settings.AudioQuality, WavFile, DestFile);
                    FFmpegProcess Worker = new FFmpegProcess(Options);
                    Result = Worker.Run("Encoder\\opusenc.exe", Args);
                }
                else if (settings.AudioAction == AudioActions.Aac || settings.AudioAction == AudioActions.Flac)
                {
                    Result = MediaEncoder.Encode(WavFile, null,
                                                 settings.AudioAction == AudioActions.Flac ? "flac" : "aac",
                                                 string.Format("-b:a {0}k", settings.AudioQuality),
                                                 DestFile,
                                                 Options);
                }
            }

            if (Result != CompletionStatus.Success || !File.Exists(DestFile))
            {
                File.Delete(DestFile);
                settings.Cancel();
            }
            return(Result);
        }
예제 #15
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);
        }
 /// <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);
 }
 public static MediaEncoderSettings Load(string filePath)
 {
     using (var stream = File.OpenRead(filePath)) {
         var serializer = new XmlSerializer(typeof(MediaEncoderSettings));
         MediaEncoderSettings Result = serializer.Deserialize(stream) as MediaEncoderSettings;
         if (Result.DeshakerSettings == null)
         {
             Result.DeshakerSettings = new MediaEncoderDeshakerSettings();
         }
         // Serialization changes new lines; restore them.
         if (Result.CustomScript != null)
         {
             Result.CustomScript = Result.CustomScript.Replace("\n", "\r\n");
         }
         return(Result);
     }
 }
        /// <summary>
        /// Starts encoding with specified settings. If an encoding is already in process, it will be added
        /// to the queue and start once the previous encodings are finished.
        /// </summary>
        /// <param name="settings">The encoding settings.</param>
        public async Task EncodeFileAsync(MediaEncoderSettings settings) {
            settings.JobIndex = ++JobIndex;
            // Files must be prepared before adding to queue so that user can replace preview files.
            DeleteJobFiles(settings);
            File.Delete(PreviewScriptFile);
            File.Delete(PreviewSettingsFile);
            if (settings.ConvertToAvi)
                SafeMove(PreviewSourceFile, settings.InputFile);
            SaveSettingsFile(settings, settings.SettingsFile);
            string Script = settings.CustomScript;
            if (string.IsNullOrEmpty(Script))
                Script = GetVideoScript(settings, settings.InputFile, false, true);
            else
                Script = Script.Replace(GetAsciiPath(PreviewSourceFile), GetAsciiPath(settings.InputFile));
            WriteFile(Script, settings.ScriptFile);

            await StartEncodeFileAsync(settings);
        }
 /// <summary>
 /// Starts encoding with specified settings. If an encoding is already in process, it will be added
 /// to the queue and start once the previous encodings are finished.
 /// </summary>
 /// <param name="settings">The encoding settings.</param>
 public async Task EncodeFileAsync(MediaEncoderSettings settings) {
     settings.JobIndex = ++JobIndex;
     // Files must be prepared before adding to queue so that user can replace preview files.
     DeleteJobFiles(settings);
     File.Delete(PreviewScriptFile);
     File.Delete(PreviewSettingsFile);
     if (settings.ConvertToAvi)
         SafeMove(PreviewSourceFile, settings.InputFile);
     SaveSettingsFile(settings, settings.SettingsFile);
     AviSynthScriptBuilder Script = new AviSynthScriptBuilder(settings.CustomScript);
     if (Script.IsEmpty)
         Script = GenerateVideoScript(settings, settings.InputFile, false, true);
     else
         Script.Replace(Script.GetAsciiPath(PreviewSourceFile), Script.GetAsciiPath(settings.InputFile));
     //Script.DitherOut(true);
     Script.WriteToFile(settings.ScriptFile);
     await StartEncodeFileAsync(settings);
 }
 private EncodingCompletedEventArgs GetEncodingResults(MediaEncoderSettings settings, string finalFile, DateTime? startTime) {
     // Create encoding result object.
     EncodingCompletedEventArgs Result = null;
     if (finalFile == null || File.Exists(finalFile)) {
         Result = new EncodingCompletedEventArgs();
         Result.Settings = settings;
         Result.OldFileName = settings.FilePath;
         Result.NewFileName = settings.FinalFile;
         if (startTime.HasValue)
             Result.EncodingTime = DateTime.Now - startTime.Value;
         if (finalFile != null) {
             FileInfo FinalFileInfo = new FileInfo(finalFile);
             Result.NewFileSize = FinalFileInfo.Length;
             FinalFileInfo = new FileInfo(settings.FilePath);
             Result.OldFileSize = FinalFileInfo.Length;
         }
     }
     return Result;
 }
        public async Task PreparePreviewFile(MediaEncoderSettings settings, bool overwrite, bool calcAutoCrop) {
            if (string.IsNullOrEmpty(settings.FilePath))
                return;

            if (overwrite) {
                File.Delete(PathManager.PreviewSourceFile);
                // Select default open method.
                if (settings.FilePath.ToLower().EndsWith(".avi"))
                    settings.ConvertToAvi = false;
                else {
                    FFmpegProcess FileInfo = await Task.Run(() => MediaInfo.GetFileInfo(settings.FilePath));
                    if (settings.ConvertToAvi && FileInfo?.VideoStream?.Height >= 720)
                        settings.ConvertToAvi = false;
                }
            }

            bool AviFileReady = File.Exists(PathManager.PreviewSourceFile);
            if (!AviFileReady && settings.ConvertToAvi)
                AviFileReady = await Task.Run(() => MediaEncoder.ConvertToAvi(settings.FilePath, PathManager.PreviewSourceFile, true, new ProcessStartOptions(FFmpegDisplayMode.Interface, "Converting to AVI"))) == CompletionStatus.Success;

            if (AviFileReady && settings.ConvertToAvi)
                await GetMediaInfo(PathManager.PreviewSourceFile, settings);
            else {
                settings.ConvertToAvi = false;
                await GetMediaInfo(settings.FilePath, settings);
            }

            // Auto-calculate crop settings.
            if (calcAutoCrop) {
                if (settings.CropLeft == 0 && settings.CropTop == 0 && settings.CropRight == 0 && settings.CropBottom == 0) {
                    Rect AutoCrop = await Task.Run(() => EncoderBusiness.GetAutoCropRect(settings.FilePath, settings.SourceHeight ?? 0, settings.SourceWidth ?? 0, null));
                    if (settings.CropLeft == 0)
                        settings.CropLeft = AutoCrop.Left;
                    if (settings.CropTop == 0)
                        settings.CropTop = AutoCrop.Top;
                    if (settings.CropRight == 0)
                        settings.CropRight = AutoCrop.Right;
                    if (settings.CropBottom == 0)
                        settings.CropBottom = AutoCrop.Bottom;
                }
            }
        }
        /// <summary>
        /// Prepares the files of an existing job that we resume.
        /// </summary>
        /// <returns>Whether job still needs to execute.</returns>
        //private bool PrepareResumeJob(MediaEncoderSettings settings) {
        //    AvisynthTools.EditStartPosition(settings.ScriptFile, 0);
        //    // At least one segment has been processed. Check if the entire file has been processed.
        //    ProcessStartOptions Options = new ProcessStartOptions(settings.JobIndex, "Resuming...", false).TrackProcess(settings);
        //    Task<long> TaskCount = Task.Run(() => AvisynthTools.GetFrameCount(settings.ScriptFile, Options));

        //    int Segment = 0;
        //    List<Task<long>> TaskList = new List<Task<long>>();
        //    while (File.Exists(PathManager.GetOutputFile(settings.JobIndex, ++Segment, settings.VideoCodec)) && settings.CompletionStatus != CompletionStatus.Cancelled) {
        //        string SegmentFile = PathManager.GetOutputFile(settings.JobIndex, Segment, settings.VideoCodec);
        //        // Discard segments of less than 10kb.
        //        if (new FileInfo(SegmentFile).Length > 10000) {
        //            int SegmentLocal = Segment;
        //            TaskList.Add(Task.Run(() => AvisynthTools.GetFrameCount(PathManager.GetOutputFile(settings.JobIndex, SegmentLocal, settings.VideoCodec), null)));
        //        } else {
        //            // There shouldn't be any resumed job following a segment that is being deleted.
        //            File.Delete(SegmentFile);
        //            break;
        //        }
        //    }

        //    long OutputFrames = 0;
        //    Task.WaitAll(TaskList.ToArray());
        //    foreach (Task<long> item in TaskList) {
        //        OutputFrames += item.Result;
        //    }

        //    TaskCount.Wait();
        //    if (settings.CompletionStatus == CompletionStatus.Cancelled)
        //        return false;

        //    long ScriptFrames = TaskCount.Result;
        //    if (OutputFrames >= ScriptFrames) {
        //        // Job completed.
        //        //EncodingCompletedEventArgs EncodeResult = FinalizeEncoding(settings, null);
        //        //if (EncodeResult != null)
        //        //    EncodingCompleted(this, EncodeResult);
        //        //else {
        //        //    PathManager.DeleteJobFiles(settings.JobIndex);
        //        //}
        //        return false;
        //    } else {
        //        // Resume with new segment.
        //        AvisynthTools.EditStartPosition(settings.ScriptFile, OutputFrames);
        //        settings.ResumeSegment = Segment;
        //        settings.ResumePos = OutputFrames;
        //        File.Delete(settings.OutputFile);
        //        return true;
        //    }
        //}

        private async Task GetMediaInfo(string previewFile, MediaEncoderSettings settings) {
            FFmpegProcess FInfo = await Task.Run(() => MediaInfo.GetFileInfo(previewFile));
            FFmpegVideoStreamInfo VInfo = FInfo.VideoStream;
            FFmpegAudioStreamInfo AInfo = settings.ConvertToAvi ? await Task.Run(() => MediaInfo.GetFileInfo(settings.FilePath).AudioStream) : FInfo.AudioStream;

            settings.SourceWidth = FInfo.VideoStream.Width;
            settings.SourceHeight = FInfo.VideoStream.Height;
            if (settings.SourceHeight > 768)
                settings.OutputHeight = settings.SourceHeight.Value;
            settings.SourceAspectRatio = (float)(VInfo?.PixelAspectRatio ?? 1);
            // Fix last track of VCDs that is widescreen.
            if (settings.SourceHeight == 288 && settings.SourceWidth == 352 && settings.SourceAspectRatio == 1.485f)
                settings.SourceAspectRatio = 1.092f;
            settings.SourceFrameRate = VInfo?.FrameRate;

            settings.SourceAudioFormat = AInfo?.Format;
            settings.SourceVideoFormat = VInfo?.Format;
            bool IsTvRange = VInfo?.ColorRange != "pc";
            if (!string.IsNullOrEmpty(VInfo?.ColorMatrix)) {
                settings.SourceColorMatrix = VInfo.ColorMatrix.EndsWith("601") ? (IsTvRange ? ColorMatrix.Rec601 : ColorMatrix.Pc601) : (IsTvRange ? ColorMatrix.Rec709 : ColorMatrix.Pc709);
            } else
                settings.SourceColorMatrix = VInfo?.Height < 600 ? (IsTvRange ? ColorMatrix.Rec601 : ColorMatrix.Pc601) : (IsTvRange ? ColorMatrix.Rec709 : ColorMatrix.Pc709);
            settings.SourceChromaPlacement = string.Compare(VInfo?.Format, "mpeg1video", true) == 0 ? ChromaPlacement.MPEG1 : ChromaPlacement.MPEG2;
            settings.DegrainPrefilter = VInfo?.Height < 600 ? DegrainPrefilters.SD : DegrainPrefilters.HD;

            settings.SourceVideoBitrate = (int)(new FileInfo(previewFile).Length / FInfo.FileDuration.TotalSeconds / 1024 * 8);
            settings.SourceAudioBitrate = AInfo?.Bitrate;
            if (!settings.HasAudioOptions)
                settings.AudioQuality = AInfo?.Bitrate > 0 ? AInfo.Bitrate : 256;
            if (settings.AudioQuality > 384)
                settings.AudioQuality = 384;
            settings.SourceBitDepth = 8; // VInfo.BitDepth;
            //settings.DenoiseD = 2;
            //settings.DenoiseA = settings.SourceHeight < 720 ? 2 : 1;
            settings.Position = FInfo.FileDuration.TotalSeconds / 2;
            settings.VideoAction = settings.SourceHeight >= 1080 ? VideoAction.x264 : VideoAction.x265;
            settings.EncodeQuality = settings.SourceHeight >= 1080 ? 23 : 22;
            settings.EncodePreset = settings.SourceHeight >= 1080 ? EncodePresets.veryslow : EncodePresets.medium;
            // Use Cache to open file when file is over 500MB
            settings.CalculateSize();
        }
예제 #23
0
 public static bool EncodeAudio(MediaEncoderSettings settings, bool silent)
 {
     if (settings.AudioAction == AudioActions.EncodeOpus)
     {
         string Args = string.Format(@"--bitrate {0} ""{1}"" ""{2}""", settings.AudioQuality, settings.AudioFileWav, settings.AudioFileOpus);
         return(Run("Encoder\\opusenc.exe", Args, silent));
     }
     else if (settings.AudioAction == AudioActions.EncodeAac || settings.AudioAction == AudioActions.EncodeFlac)
     {
         string Args = string.Format(@"-i {2}{0} -b:a {1}k {3}",
                                     settings.AudioAction == AudioActions.EncodeFlac ? " -c:a flac" : "",
                                     settings.AudioQuality,
                                     settings.AudioFileWav,
                                     settings.AudioAction == AudioActions.EncodeFlac ? settings.AudioFileFlac : settings.AudioFileAac);
         return(Run("Encoder\\ffmpeg.exe", Args, silent));
     }
     else
     {
         return(true);
     }
 }
        /// <summary>
        /// For files encoded in various segments (stop/resume), merge the various segments.
        /// </summary>
        private CompletionStatus MergeSegments(MediaEncoderSettings settings, string destination) {
            MediaEncoderSegments segBusiness = new MediaEncoderSegments();
            segBusiness.Analyze(settings);
            if (segBusiness.SegLeft.Count() > 0)
                return CompletionStatus.Error;

            List<string> SegmentList = new List<string>();
            foreach (SegmentInfo seg in segBusiness.SegDone) {
                SegmentList.Add(PathManager.GetOutputFile(settings.JobIndex, seg.Start, settings.Container));
            }

            CompletionStatus Result = CompletionStatus.Success;
            File.Delete(destination);
            if (SegmentList.Count == 1)
                File.Move(SegmentList[0], destination);
            else if (SegmentList.Count > 1) {
                Result = MediaMuxer.Concatenate(SegmentList, destination, new ProcessStartOptions(settings.JobIndex, "Merging Files", false));
            }
            settings.CompletionStatus = Result;
            return Result;
        }
 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 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);
            }
        }
예제 #27
0
        /// <summary>
        /// Returns the audio gain that can be applied to an audio file.
        /// </summary>
        /// <param name="settings">The settings pointing to the file to analyze.</param>
        /// <returns>A float value representing the audio gain that can be applied, or null if it failed.</returns>
        public static float?GetAudioGain(MediaEncoderSettings settings)
        {
            string TempResult = settings.TempFile + ".txt";
            string Args       = string.Format(@"""{0}ffmpeg.exe"" -i ""{1}"" -af ""volumedetect"" -f null null > ""{1}"" 2>&1",
                                              Settings.AviSynthPluginsPath, settings.FilePath, TempResult);

            Run("cmd", CommandPipe(Args), true);
            float?Result = null;

            if (File.Exists(TempResult))
            {
                string FileString = File.ReadAllText(TempResult);
                // Find max_volume.
                string SearchVal = "max_volume: ";
                int    Pos1      = FileString.IndexOf(SearchVal);
                if (Pos1 >= 0)
                {
                    Pos1 += SearchVal.Length;
                    // Find end of line.
                    int Pos2 = FileString.IndexOf('\r', Pos1);
                    if (Pos2 >= 0)
                    {
                        string MaxVolString = FileString.Substring(Pos1, Pos2 - Pos1);
                        if (MaxVolString.Length > 3)
                        {
                            // Remove ' dB'
                            MaxVolString = MaxVolString.Substring(0, MaxVolString.Length - 3);
                            float MaxVol = 0;
                            if (float.TryParse(MaxVolString, out MaxVol))
                            {
                                Result = Math.Abs(MaxVol);
                            }
                        }
                    }
                }
                File.Delete(TempResult);
            }
            return(Result);
        }
        /// <summary>
        /// Automatically reloads jobs if the encoder was unexpectedly closed.
        /// </summary>
        public void AutoLoadJobs() {
            try {
                if (!Directory.Exists(PathManager.TempFilesPath))
                    Directory.CreateDirectory(PathManager.TempFilesPath);
            }
            catch {
                return;
            }

            var JobList = Directory.EnumerateFiles(PathManager.TempFilesPath, "Job*_Settings.xml");
            int Index = 0;
            MediaEncoderSettings settings;
            //List<Task> TaskList = new List<Task>();

            // Get list of interrupted jobs.
            foreach (string item in JobList) {
                // Load settings file.
                settings = null;
                try {
                    settings = MediaEncoderSettings.Load(item);
                }
                catch { }

                // Resume job.
                if (int.TryParse(Path.GetFileName(item).Replace("Job", "").Replace("_Settings.xml", ""), out Index)) {
                    if (Index > JobIndex)
                        JobIndex = Index;

                    if (settings != null && File.Exists(settings.InputFile) && File.Exists(settings.ScriptFile) && File.Exists(settings.SettingsFile) && File.Exists(settings.FilePath)) {
                        ProcessingQueue.Add(settings);
                        //TaskList.Add(StartJobAsync(settings));
                    } else {
                        // Resume job failed, delete files.
                        PathManager.DeleteJobFiles(settings.JobIndex);
                    }
                }
            }
        }
        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;
        }
예제 #30
0
        /// <summary>
        /// Encodes specified file into H264 format. The script file must already be written.
        /// </summary>
        /// <param name="settings">An object containing the encoding settings.</param>
        /// <returns>Whether the operation was completed.</returns>
        public static bool EncodeVideo(MediaEncoderSettings settings)
        {
            File.Delete(settings.OutputFile);
            string PipeArgs;

            if (settings.VideoCodec == VideoCodecs.x264)
            {
                PipeArgs = string.Format(@"""{0}avs2yuv.exe"" ""{1}"" -o - | ""{0}ffmpeg.exe"" -y -i - -an -c:v libx264 -psy-rd 1:0.05 -preset {2} -crf {3} ""{4}""",
                                         Settings.AviSynthPluginsPath, settings.ScriptFile, settings.EncodePreset, settings.EncodeQuality, settings.OutputFile);
            }
            else if (settings.VideoCodec == VideoCodecs.x265)
            {
                PipeArgs = string.Format(@"""{0}avs2yuv.exe"" ""{1}"" -o - | ""{0}ffmpeg.exe"" -y -i - -an -c:v libx265 -preset {2} -crf {3} ""{4}""",
                                         Settings.AviSynthPluginsPath, settings.ScriptFile, settings.EncodePreset, settings.EncodeQuality, settings.OutputFile);
            }
            else     // AVI
            {
                PipeArgs = string.Format(@"""{0}avs2yuv.exe"" ""{1}"" -o - | ""{0}ffmpeg.exe"" -y -i - -an -c:v utvideo ""{4}""",
                                         Settings.AviSynthPluginsPath, settings.ScriptFile, settings.EncodePreset, settings.EncodeQuality, settings.OutputFile);
            }
            //}
            return(Run("cmd", CommandPipe(PipeArgs), false));
        }
        public void SaveSettingsFile(MediaEncoderSettings settings, string fileName) {
            Directory.CreateDirectory(Path.GetDirectoryName(fileName));

            using (var writer = new StreamWriter(fileName)) {
                var serializer = new XmlSerializer(typeof(MediaEncoderSettings));
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add("", "");
                serializer.Serialize(writer, settings, ns);
                writer.Flush();
            }
        }
        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);
        }
 public void ApplyInterFrame(AviSynthScriptBuilder Script, MediaEncoderSettings settings, int CPU) {
     Script.LoadPluginDll("svpflow1.dll");
     Script.LoadPluginDll("svpflow2.dll");
     Script.LoadPluginAvsi("InterFrame2.avsi");
     if (settings.IncreaseFrameRateValue == FrameRateModeEnum.Double)
         Script.AppendLine(@"InterFrame(Cores={0}{1}, FrameDouble=true{2})", CPU, 
             settings.IncreaseFrameRateSmooth ? @", Tuning=""Smooth""" : "",
             Settings.SavedFile.EnableMadVR ? ", GPU=true" : "");
     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(@"InterFrame(Cores={0}{1}, NewNum={2}, NewDen={3}, GPU=true)", CPU, 
             settings.IncreaseFrameRateSmooth ? @", Tuning=""Smooth""" : "",
             NewNum, NewDen);
     }
 }
        /// <summary>
        /// Encodes specified video file according to settings. The script file must already be written.
        /// </summary>
        /// <param name="settings">An object containing the encoding settings.</param>
        /// <param name="frameCount">The amount of frames to process.</param>
        /// <param name="totalFrameCount">If encoding in various segments, the total amount of frames in the script.</param>
        /// <returns>The endoding completion status..</returns>
        public static CompletionStatus EncodeVideo(MediaEncoderSettings settings, long frameCount, long totalFrameCount)
        {
            CompletionStatus Result = CompletionStatus.None;

            File.Delete(settings.OutputFile);
            string Codec = "", Args = "";

            if (settings.VideoAction == VideoAction.x264)
            {
                Codec = "libx264";
            }
            else if (settings.VideoAction == VideoAction.x265)
            {
                Codec = "libx265";
                Args  = string.Format("-preset {0} -crf {1}", settings.EncodePreset, settings.EncodeQuality);
            }
            else if (settings.VideoAction == VideoAction.Avi)
            {
                Codec = "huffyuv";
            }
            else if (settings.VideoAction == VideoAction.AviUtVideo)
            {
                Codec = "utvideo";
            }
            else if (settings.VideoAction == VideoAction.xvid)
            {
                Codec = "xvid";
            }
            else if (settings.VideoAction == VideoAction.x264_10bit)
            {
                Args = string.Format("--preset {0} --crf {1}", settings.EncodePreset, settings.EncodeQuality);
            }

            if (settings.ParallelProcessing > 1)
            {
                Args += settings.VideoAction == VideoAction.x264_10bit ? " --threads 4" : " -threads 4";
            }

            ProcessStartOptions Options = new ProcessStartOptions(settings.JobIndex, "Processing Video", true).TrackProcess(settings);

            // Options.FrameCount = AvisynthTools.GetFrameCount(settings.ScriptFile, new ProcessStartOptions(settings.JobIndex, "Getting Frame Count", false).TrackProcess(settings));
            Options.FrameCount      = frameCount;
            Options.ResumePos       = settings.ResumePos;
            Options.TotalFrameCount = totalFrameCount;
            if (settings.CompletionStatus == CompletionStatus.Success)
            {
                string JobScript = settings.OutputScriptFile;
                File.Delete(JobScript);
                File.Copy(settings.ScriptFile, JobScript);
                EditStartPosition(JobScript, settings.ResumePos, settings.ResumePos + frameCount - 1);
                if (settings.VideoAction == VideoAction.x264_10bit)
                {
                    Result = EncodeX264_10bit(JobScript, Args, settings.OutputFile, Options);
                }
                else
                {
                    Result = MediaEncoder.Encode(JobScript, Codec, null, Args, settings.OutputFile, Options);
                }
                File.Delete(JobScript);
            }
            else
            {
                Result = settings.CompletionStatus;
            }
            return(Result);
        }
        public async Task PreparePreviewFile(MediaEncoderSettings settings, bool overwrite) {
            if (string.IsNullOrEmpty(settings.FileName))
                return;

            if (overwrite) {
                File.Delete(PreviewSourceFile);
                // Select default open method.
                if (settings.FileName.ToLower().EndsWith(".avi"))
                    settings.ConvertToAvi = false;
                else {
                    using (MediaInfoReader InfoReader = new MediaInfoReader()) {
                        InfoReader.LoadInfo(Settings.NaturalGroundingFolder + settings.FileName);
                        if (settings.ConvertToAvi && InfoReader.Height.HasValue && InfoReader.Height >= 720)
                            settings.ConvertToAvi = false;
                    }
                }
            }

            bool AviFileReady = File.Exists(PreviewSourceFile);
            if (!AviFileReady && settings.ConvertToAvi) 
                AviFileReady = await Task.Run(() => FfmpegBusiness.ConvertToAVI(Settings.NaturalGroundingFolder + settings.FileName, PreviewSourceFile, false));

            if (AviFileReady && settings.ConvertToAvi)
                await GetMediaInfo(PreviewSourceFile, settings);
            else {
                settings.ConvertToAvi = false;
                await GetMediaInfo(Settings.NaturalGroundingFolder + settings.FileName, settings);
            }

            // Auto-calculate crop settings.
            if (settings.CropLeft == 0 && settings.CropTop == 0 && settings.CropRight == 0 && settings.CropBottom == 0) {
                Rect AutoCrop = await Task.Run(() => FfmpegBusiness.GetAutoCropRect(settings, true));
                if (settings.CropLeft == 0)
                    settings.CropLeft = AutoCrop.Left;
                if (settings.CropTop == 0)
                    settings.CropTop = AutoCrop.Top;
                if (settings.CropRight == 0)
                    settings.CropRight = AutoCrop.Right;
                if (settings.CropBottom == 0)
                    settings.CropBottom = AutoCrop.Bottom;
            }
        }
 private async Task GetMediaInfo(string previewFile, MediaEncoderSettings settings) {
     MediaInfoReader InfoReader = new MediaInfoReader();
     await InfoReader.LoadInfoAsync(previewFile);
     settings.SourceWidth = InfoReader.Width;
     settings.SourceHeight = InfoReader.Height;
     settings.SourceAspectRatio = InfoReader.PixelAspectRatio ?? 1;
     // Fix last track of VCDs that is widescreen.
     if (settings.SourceHeight == 288 && settings.SourceWidth == 352 && settings.SourceAspectRatio == 1.485f)
         settings.SourceAspectRatio = 1.092f;
     settings.SourceFrameRate = InfoReader.FrameRate;
     if (settings.ConvertToAvi)
         await InfoReader.LoadInfoAsync(Settings.NaturalGroundingFolder + settings.FileName);
     settings.AudioRequiresMkv = (InfoReader.AudioFormat != "AAC");
     settings.Position = (InfoReader.Length ?? 0) / 2;
 }
 public bool CustomScriptHasChanges(MediaEncoderSettings settings) {
     return settings.CustomScript != GetVideoScript(settings, GetPreviewSourceFile(settings), false, true);
 }
 public void DeleteJobFiles(MediaEncoderSettings settings) {
     if (settings.ConvertToAvi)
         File.Delete(settings.InputFile);
     File.Delete(settings.OutputFile);
     File.Delete(settings.FinalFile);
     File.Delete(settings.ScriptFile);
     File.Delete(settings.SettingsFile);
 }
 public string GetPreviewSourceFile(MediaEncoderSettings settings) {
     if (settings.ConvertToAvi)
         return PreviewSourceFile;
     else
         return Settings.NaturalGroundingFolder + settings.FileName;
 }
 public bool EncodeAudio(MediaEncoderSettings settings) {
     FfmpegBusiness.SaveAudioToWav(settings, true);
     return FfmpegBusiness.EncodeAudio(settings, true);
 }
 /// <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, PreviewSourceFile);
     SaveSettingsFile(settings, PreviewSettingsFile);
 }
        public void SaveSettingsFile(MediaEncoderSettings settings, string fileName) {
            Directory.CreateDirectory(Path.GetDirectoryName(fileName));

            using (var writer = new StreamWriter(fileName)) {

                var serializer = new XmlSerializer(typeof(MediaEncoderSettings));
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add("", "");
                XmlWriterSettings ws = new XmlWriterSettings();
                ws.NewLineHandling = NewLineHandling.Entitize;
                using (XmlWriter wr = XmlWriter.Create(writer, ws)) {
                    serializer.Serialize(wr, settings, ns);
                }
                writer.Flush();
            }
        }
 public bool CustomScriptHasChanges(MediaEncoderSettings settings) {
     return settings.CustomScript.Replace("\r\n", "\n") != GenerateVideoScript(settings, GetPreviewSourceFile(settings), false, true).Script.Replace("\r\n", "\n");
 }
        public async Task OpenPreview(MediaEncoderSettings settings, bool overwrite) {
            if (string.IsNullOrEmpty(settings.FileName))
                return;

            if (overwrite)
                File.Delete(PreviewSourceFile);

            bool IsCompleted = File.Exists(PreviewSourceFile) || !settings.ConvertToAvi || 
                await Task.Run(() => FfmpegBusiness.ConvertToAVI(Settings.NaturalGroundingFolder + settings.FileName, PreviewSourceFile, false));
            if (IsCompleted && settings.ConvertToAvi)
                await GetMediaInfo(PreviewSourceFile, settings);
            else {
                settings.ConvertToAvi = false;
                await GetMediaInfo(Settings.NaturalGroundingFolder + settings.FileName, settings);
            }
        }
 private async Task GetMediaInfo(string previewFile, MediaEncoderSettings settings) {
     using (MediaInfoReader InfoReader = new MediaInfoReader()) {
         await InfoReader.LoadInfoAsync(previewFile);
         settings.SourceWidth = InfoReader.Width;
         settings.SourceHeight = InfoReader.Height;
         settings.SourceAspectRatio = InfoReader.PixelAspectRatio ?? 1;
         if (settings.SourceAspectRatio != 1) {
             // Get aspect ratio from FFMPEG which is more accurate.
             float? SAR = FfmpegBusiness.GetPixelAspectRatio(settings);
             if (SAR.HasValue)
                 settings.SourceAspectRatio = SAR.Value;
         }
         // Fix last track of VCDs that is widescreen.
         if (settings.SourceHeight == 288 && settings.SourceWidth == 352 && settings.SourceAspectRatio == 1.485f)
         settings.SourceAspectRatio = 1.092f;
         settings.SourceFrameRate = InfoReader.FrameRate;
         if (settings.ConvertToAvi)
             await InfoReader.LoadInfoAsync(Settings.NaturalGroundingFolder + settings.FileName);
         settings.SourceAudioFormat = InfoReader.AudioFormat;
         settings.SourceVideoFormat = InfoReader.VideoFormat;
         settings.SourceColorMatrix = InfoReader.Height < 720 ? ColorMatrix.Rec601 : ColorMatrix.Rec709;
         if (!settings.CanCopyAudio)
             settings.EncodeFormat = VideoFormats.Mkv;
         settings.SourceAudioBitrate = InfoReader.AudioBitRate;
         settings.SourceBitDepth = InfoReader.BitDepth;
         settings.Position = (InfoReader.Length ?? 0) / 2;
         settings.CalculateSize();
     }
 }
 public void GenerateCustomScript(MediaEncoderSettings settings) {
     settings.CustomScript = GetVideoScript(settings, GetPreviewSourceFile(settings), false, true);
 }
 public void SetEncodeSettings(MediaEncoderSettings value) {
     isBinding = true;
     SettingsTab.SelectedIndex = (String.IsNullOrEmpty(value.CustomScript) ? 0 : 2);
     encodeSettings = value;
     this.DataContext = value;
     isBinding = false;
 }
        public string GetVideoScript(MediaEncoderSettings settings, string inputFile, bool preview, bool multiThreaded) {
            int CPU = Environment.ProcessorCount;
            if (CPU > 4 && (settings.DoubleNNEDI3Before || settings.DoubleEEDI3 || settings.DoubleNNEDI3))
                CPU = 4; // Limit to 4 threads when NNEDI3 or EEDI3 is the bottleneck.
            bool AviSynthPlus = false;
            // multiThreaded = true;

            // Calculate CropSource and CropAfter values.
            bool CropSource = false;
            int CropSourceLeft = 0;
            int CropSourceTop = 0;
            int CropSourceRight = 0;
            int CropSourceBottom = 0;
            bool CropAfter = false;
            int CropAfterLeft = 0;
            int CropAfterTop = 0;
            int CropAfterRight = 0;
            int CropAfterBottom = 0;
            if (settings.Crop) {
                // CropSource must be a factor of two.
                CropSourceLeft = settings.CropLeft / 2 * 2;
                CropSourceTop = settings.CropTop / 2 * 2;
                CropSourceRight = settings.CropRight / 2 * 2;
                CropSourceBottom = settings.CropBottom / 2 * 2;
            }
            int ScaleFactor = (settings.DoubleNNEDI3Before ? 2 : 1) * (settings.DoubleEEDI3 ? 2 : 1) * (settings.DoubleNNEDI3 ? 2 : 1);
            int ExtraDouble = 0;
            // If cropping makes the output smaller than the resize dimension, keep doubling to enlarge.
            if (settings.Resize) {
                while ((settings.SourceHeight - CropSourceTop - CropSourceBottom) * ScaleFactor < settings.ResizeHeight) {
                    ExtraDouble += 2;
                    ScaleFactor *= 2;
                }
            }
            if (settings.Crop) {
                CropAfterTop = (settings.CropTop - CropSourceTop) * ScaleFactor;
                CropAfterLeft = (settings.CropLeft - CropSourceLeft) * ScaleFactor;
                CropAfterRight = (settings.CropRight - CropSourceRight) * ScaleFactor;
                CropAfterBottom = (settings.CropBottom - CropSourceBottom) * ScaleFactor;
                CropSource = (CropSourceLeft > 0 || CropSourceRight > 0 || CropSourceTop > 0 || CropSourceBottom > 0);
                CropAfter = (CropAfterLeft > 0 || CropAfterRight > 0 || CropAfterTop > 0 || CropAfterBottom > 0);
            }
            // Calculate encoding and final frame rates.
            double ChangeSpeedValue = settings.ChangeSpeed ? (double)settings.ChangeSpeedValue / 100 : 1;
            double FrameRateBefore = settings.SourceFrameRate.Value * ChangeSpeedValue;

            // Generate video script.
            StringBuilder Script = new StringBuilder();
            if (multiThreaded) {
                // Script.AppendLine("Setmemorymax(1024)");
                if (AviSynthPlus) {
                    Script.AppendLine(@"SetFilterMTMode(""DEFAULT_MT_MODE"",2)");
                    Script.AppendLine(@"SetFilterMTMode(""AviSource"",3)");
                } else {
                    Script.AppendFormat("SetMTMode(3,{0})", CPU).AppendLine();
                }
            }
            Script.AppendFormat(@"PluginPath = ""{0}""", GetAsciiPath(Settings.AviSynthPluginsPath)).AppendLine();
            if (settings.ConvertToAvi)
                Script.AppendFormat(@"AviSource(""{0}"", audio=false, pixel_type=""YV12"")", GetAsciiPath(inputFile)).AppendLine(); //.ConvertToYV12()
            else
                Script.AppendFormat(@"DirectShowSource(""{0}"", audio=false, pixel_type=""YV12""{1})", GetAsciiPath(inputFile), settings.SourceFrameRate.HasValue ? ", fps=" + settings.SourceFrameRate : string.Empty).AppendLine(); //.ConvertToYV12()
            if (multiThreaded && !AviSynthPlus)
                Script.AppendLine("SetMTMode(2)");
            if (settings.FixColors && !preview) {
                LoadPluginDll(Script, "ColorMatrix.dll");
                Script.AppendLine(@"ColorMatrix(mode=""Rec.601->Rec.709"")");
            }
            if (FrameRateBefore != settings.SourceFrameRate)
                Script.AppendFormat(CultureInfo.InvariantCulture, "AssumeFPS({0})", FrameRateBefore).AppendLine();
            if (settings.Trim) {
                Script.AppendFormat("Trim({0}, {1})",
                    settings.TrimStart.HasValue ? settings.TrimStart.Value * settings.SourceFrameRate.Value : 0,
                    settings.TrimEnd.HasValue && !preview ? settings.TrimEnd.Value * settings.SourceFrameRate.Value : 0).AppendLine();
            }
            if (CropSource) {
                Script.AppendFormat("Crop({0}, {1}, -{2}, -{3})", CropSourceLeft, CropSourceTop, CropSourceRight, CropSourceBottom).AppendLine();
            }
            if (settings.Denoise || settings.SharpenAfterDouble || settings.SharpenFinal)
                LoadPluginDll(Script, "FFT3DFilter.dll");
            if (settings.Denoise) {
                Script.AppendFormat(CultureInfo.InvariantCulture, @"fft3dfilter(sigma={0}, bt=5, bw=48, bh=48, ow=24, oh=24, sharpen={1}, ncpu={2})",
                    ((double)settings.DenoiseStrength / 10).ToString(CultureInfo.InvariantCulture),
                    (double)settings.SharpenAfterDoubleStrength / 100,
                    CPU).AppendLine();
            }
            //if (settings.SharpenAfterDouble || settings.SharpenFinal) {
            //    LoadPluginDll(Script, "masktools2.dll");
            //    LoadPluginDll(Script, "RgTools.dll");
            //    LoadPluginAvsi(Script, "LSFmod.avsi");
            //}
            if (settings.DoubleNNEDI3 || settings.DoubleNNEDI3Before || ExtraDouble > 0)
                LoadPluginDll(Script, "nnedi3.dll");
            if (settings.DoubleNNEDI3Before) {
                Script.AppendLine("nnedi3_rpow2 (2)");
                if (settings.SharpenAfterDouble && (settings.DoubleEEDI3 || (settings.DoubleNNEDI3 || ExtraDouble > 0)))
                    // Script.AppendFormat(@"LSFmod(strength={0}, defaults=""slow"")", settings.SharpenAfterDoubleStrength).AppendLine();
                    Script.AppendFormat(CultureInfo.InvariantCulture, @"fft3dfilter(bt=-1, sharpen={0}, ncpu={1})", (double)settings.SharpenAfterDoubleStrength / 100, CPU).AppendLine();
            }
            if (settings.DoubleEEDI3) {
                LoadPluginDll(Script, "eedi3.dll");
                Script.AppendLine("eedi3_rpow2 (2)");
                if (settings.SharpenAfterDouble && (settings.DoubleNNEDI3 || ExtraDouble > 0))
                    // Script.AppendFormat(@"LSFmod(strength={0}, defaults=""slow"")", settings.SharpenAfterDoubleStrength).AppendLine();
                    Script.AppendFormat(CultureInfo.InvariantCulture, @"fft3dfilter(bt=-1, sharpen={0}, ncpu={1})", (double)settings.SharpenAfterDoubleStrength / 100, CPU).AppendLine();
            }
            if (settings.DoubleNNEDI3 || ExtraDouble > 0) {
                Script.AppendFormat("nnedi3_rpow2 ({0})", (settings.DoubleNNEDI3 ? 2 : 0) + ExtraDouble).AppendLine();
            }
            if (settings.Resize || settings.SourceAspectRatio != 1 || CropAfter) {
                // Calculate width for resize.
                if (!settings.Resize) // If pixels are not square, we must always resize to preserve aspect ratio.
                    settings.ResizeHeight = settings.SourceHeight.Value * ScaleFactor;
                int CropHeight = ((settings.SourceHeight.Value - CropSourceTop - CropSourceBottom) * ScaleFactor);
                int CropWidth = ((settings.SourceWidth.Value - CropSourceLeft - CropSourceRight) * ScaleFactor);
                if (CropAfter) {
                    CropHeight = CropHeight - CropAfterTop - CropAfterBottom;
                    CropWidth = CropWidth - CropAfterLeft - CropAfterRight;
                }
                int ResizeWidth = (int)Math.Round((double)CropWidth * settings.SourceAspectRatio / CropHeight * settings.ResizeHeight / 4) * 4;
                if (CropAfter) {
                    Script.AppendFormat("Spline36Resize({0}, {1}, {2}, {3}, -{4}, -{5})",
                        ResizeWidth, settings.ResizeHeight, CropAfterLeft, CropAfterTop, CropAfterRight, CropAfterBottom).AppendLine();
                } else {
                    Script.AppendFormat("Spline36Resize({0}, {1})", ResizeWidth, settings.ResizeHeight).AppendLine();
                }
            }
            if (settings.IncreaseFrameRate) {
                LoadPluginDll(Script, "svpflow1.dll");
                LoadPluginDll(Script, "svpflow2.dll");
                LoadPluginAvsi(Script, "InterFrame2.avsi");
                if (settings.IncreaseFrameRateValue == FrameRateModeEnum.Double)
                    Script.AppendFormat(@"InterFrame(Cores={0}, Tuning=""Smooth"", FrameDouble=true{1})", CPU, Settings.SavedFile.EnableMadVR ? ", GPU=true" : "").AppendLine();
                else {
                    int NewNum = 0;
                    int NewDen = 0;
                    if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps30) {
                        NewNum = 30000;
                        NewDen = 1001;
                    } else if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps60) {
                        NewNum = 60000;
                        NewDen = 1001;
                    } else if (settings.IncreaseFrameRateValue == FrameRateModeEnum.fps120) {
                        NewNum = 120000;
                        NewDen = 1001;
                    }
                    Script.AppendFormat(@"InterFrame(Cores={0}, Tuning=""Smooth"", NewNum={1}, NewDen={2}{3})", CPU, NewNum, NewDen, Settings.SavedFile.EnableMadVR ? ", GPU=true" : "").AppendLine();
                }
            }
            if (settings.SharpenFinal)
                // Script.AppendFormat(@"LSFmod(strength={0}, defaults=""slow"")", settings.SharpenFinalStrength).AppendLine();
                Script.AppendFormat(CultureInfo.InvariantCulture, @"fft3dfilter(bt=-1, sharpen={0}, ncpu={1})", (double)settings.SharpenFinalStrength / 100, CPU).AppendLine();
            if (preview && (settings.Crop))
                Script.AppendLine("AddBorders(2, 2, 2, 2, $FFFFFF)");
            if (preview)
                Script.AppendLine("ConvertToRGB32()");
            if (multiThreaded) {
                if (AviSynthPlus)
                    Script.AppendLine("Prefetch(4)");
                else
                    Script.AppendLine("Distributor()");
            }
            return Script.ToString();
        }
 /// <summary>
 /// Tracks the process that will be run into a MediaEncoderSettings object.
 /// </summary>
 /// <param name="options">The options object used to track process status.</param>
 /// <param name="settings">The settings object that will store the process reference.</param>
 /// <returns>The options object.</returns>
 public static ProcessStartOptions TrackProcess(this ProcessStartOptions options, MediaEncoderSettings settings)
 {
     options.Started += (sender, e) => {
         if (settings.Processes == null)
         {
             settings.Processes = new List <FFmpegProcess>();
         }
         settings.Processes.Add(e.Process);
         e.Process.Completed += (sender2, e2) => {
             settings.CompletionStatus = e2.Status;
             settings.Processes.Remove(e.Process);
         };
     };
     return(options);
 }
 private EncodingCompletedEventArgs GetEncodingResults(MediaEncoderSettings settings, string finalFile, DateTime? startTime) {
     // Create encoding result object.
     EncodingCompletedEventArgs Result = null;
     if (File.Exists(finalFile)) {
         Result = new EncodingCompletedEventArgs();
         Result.OldFileName = settings.FileName;
         Result.NewFileName = settings.FinalFile.Substring(Settings.NaturalGroundingFolder.Length);
         if (startTime.HasValue)
             Result.EncodingTime = DateTime.Now - startTime.Value;
         FileInfo FinalFileInfo = new FileInfo(finalFile);
         Result.NewFileSize = FinalFileInfo.Length;
         FinalFileInfo = new FileInfo(Settings.NaturalGroundingFolder + settings.FileName);
         Result.OldFileSize = FinalFileInfo.Length;
         Result.Settings = settings;
     }
     return Result;
 }
        public AviSynthScriptBuilder GenerateVideoScript(MediaEncoderSettings settings, string inputFile, bool preview, bool multiThreaded) {
            int CPU = Environment.ProcessorCount;
            if (CPU <= 1)
                multiThreaded = false;
            bool AviSynthPlus = (Settings.EncoderAviSynthVersion == AviSynthVersion.AviSynthPlus);
            // multiThreaded = true;

            settings.CalculateSize();

            // 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();
            bool IsYV24 = false;
            Script.AppendLine(); // After clean-up, this adds a line after LoadPlugin commands.
            Script.AddPluginPath();
            if (multiThreaded) {
                // Script.AppendLine("Setmemorymax(1500)");
                if (AviSynthPlus) {
                    Script.LoadPluginAvsi("AviSynthMT.avsi");
                    //Script.AppendLine(@"SetFilterMTMode(""DEFAULT_MT_MODE"",2)");
                    //Script.AppendLine(@"SetFilterMTMode(""LWLibavVideoSource"",3)");
                    //Script.AppendLine(@"SetFilterMTMode(""LWLibavAudioSource"",3)");
                    //if (settings.Denoise1)
                    //    Script.AppendLine(@"SetFilterMTMode(""KNLMeansCL"",3)");
                } else {
                    Script.AppendLine("SetMTMode(3,{0})", CPU);
                }
            }
            if (settings.ConvertToAvi || inputFile.ToLower().EndsWith(".avi"))
                Script.OpenAvi(inputFile, !string.IsNullOrEmpty(settings.SourceAudioFormat));
            else
                Script.OpenDirect(inputFile, null, !string.IsNullOrEmpty(settings.SourceAudioFormat), 1);
            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 && !preview ? (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);
            }
            if (settings.Denoise1) {
                if (GpuSupport == SupportedOpenClVersion.v12)
                    Script.LoadPluginDll("KNLMeansCL.dll");
                else
                    Script.LoadPluginDll("KNLMeansCL-6.11.dll");
                Script.AppendLine("ConvertToYV24()");
                IsYV24 = true;
                if (multiThreaded && !AviSynthPlus)
                    Script.AppendLine("SetMTMode(5)");
                Script.AppendLine(CultureInfo.InvariantCulture, @"KNLMeansCL(D=1, A=2, h={0}, cmode=true, device_type=""{1}""{2})", 
                    ((double)settings.Denoise1Strength / 10).ToString(CultureInfo.InvariantCulture), 
                    GpuSupport != SupportedOpenClVersion.None ? "GPU" : "CPU",
                    GpuSupport != SupportedOpenClVersion.None ? ", device_id=" + Settings.SavedFile.GraphicDeviceId.ToString() : "");
            }
            if (multiThreaded && !AviSynthPlus)
                Script.AppendLine("SetMTMode(2)");
            if (settings.FrameDouble > 0 || settings.SourceColorMatrix == ColorMatrix.Rec601) {
                Script.LoadPluginDll("Shaders\\Shader.dll");
                Script.LoadPluginAvsi("Shaders\\Shader.avsi");
            }
            bool HasNoShader = (!settings.SuperRes && settings.UpscaleMethod == UpscaleMethods.NNedi3 && settings.DownscaleMethod == DownscaleMethods.Bicubic);
            if (settings.SourceColorMatrix == ColorMatrix.Rec601 && settings.FrameDouble == 0 || HasNoShader) {
                Script.AppendLine("ColorMatrixShader(MatrixIn=\"601\")");
            }
            if (settings.Denoise2) {
                Script.LoadPluginDll("FFT3DFilter.dll");
                Script.AppendLine(CultureInfo.InvariantCulture, @"fft3dfilter(sigma={0}, bt=5, bw=48, bh=48, ow=24, oh=24, sharpen={1})",
                    ((double)settings.Denoise2Strength / 10).ToString(CultureInfo.InvariantCulture),
                    (double)settings.Denoise2Sharpen / 100);
            }

            if (settings.FrameDouble > 0) {
                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");

                bool IsLastDouble = false;
                if (settings.UpscaleMethod == UpscaleMethods.NNedi3) {
                    if (IsYV24) {
                        Script.AppendLine("ConvertToYV12()");
                        IsYV24 = false;
                    }
                    Script.LoadPluginDll("nnedi3.dll");
                    //Script.LoadPluginDll("FTurn.dll");
                    Script.LoadPluginAvsi("edi_rpow2.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})",
                                settings.SuperRes3Passes ? (i == 0 && settings.FrameDouble > 1 ? 5 : 3) : 2, 
                                settings.SuperResStrength / 100f, settings.SuperResSoftness / 100f, DoubleScript,
                                i == 0 && settings.SourceColorMatrix == ColorMatrix.Rec601 ? ", MatrixIn=\"601\"" : "",
                                IsLastDouble && settings.DownscaleMethod == DownscaleMethods.SSim ? ", " + FinalResize : "");
                        } else {
                            Script.AppendLine(DoubleScript);
                            if (IsLastDouble && settings.DownscaleMethod == DownscaleMethods.SSim) {
                                Script.AppendLine("SSimDownscaler({0}{1})", 
                                    FinalResize.Replace(" f", " ").Replace("fW", "W"), // Use same string as FinalResize but remove 'f' parameter sufix.
                                    settings.SourceColorMatrix == ColorMatrix.Rec601 ? ", MatrixIn=\"601\"" : "");
                            }
                        }
                        if (i == 0 && settings.IncreaseFrameRate)
                            ApplyInterFrame(Script, settings, CPU);
                    }
                } else { // UpscaleMethod == SuperXBR
                    for (int i = 0; i < settings.FrameDouble; i++) {
                        IsLastDouble = i == settings.FrameDouble - 1;
                        if (settings.SuperRes) {
                            Script.AppendLine(CultureInfo.InvariantCulture, @"SuperResXBR({0}, {1}, {2}, XbrStr={3}, XbrSharp={4}{5}{6})",
                                settings.SuperRes3Passes ? (i == 0 && settings.FrameDouble > 1 ? 5 : 3) : 2,
                                settings.SuperResStrength / 100f, settings.SuperResSoftness / 100f,
                                settings.SuperXbrStrength / 10f, settings.SuperXbrSharpness / 10f,
                                i == 0 && settings.SourceColorMatrix == ColorMatrix.Rec601 ? ", MatrixIn=\"601\"" : "",
                                IsLastDouble ? ", " + FinalResize : "");
                        } else {
                            Script.AppendLine("SuperXBR(Str={0}, Sharp={1}{2}{3})",
                                settings.SuperXbrStrength / 10f, settings.SuperXbrSharpness / 10f,
                                i == 0 && settings.SourceColorMatrix == ColorMatrix.Rec601 ? ", MatrixIn=\"601\"" : "",
                                IsLastDouble ? ", " + FinalResize : "");
                        }
                        if (i == 0 && settings.IncreaseFrameRate) {
                            if (IsYV24) {
                                Script.AppendLine("ConvertToYV12()");
                                IsYV24 = false;
                            }
                            ApplyInterFrame(Script, settings, CPU);
                        }
                    }
                }
            }
            if (IsYV24) {
                Script.AppendLine("ConvertToYV12()");
                IsYV24 = false;
            }
            if (settings.FrameDouble == 0 && settings.IncreaseFrameRate)
                ApplyInterFrame(Script, settings, CPU);

            Script.LoadPluginAvsi("ResizeX.avsi");
            if (settings.CropAfter.HasValue || settings.FrameDouble == 0) {
                bool ApplyResize = settings.FrameDouble == 0 || HasNoShader;
                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" : "");
            }

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

            Script.Cleanup();
            return Script;
        }
        private EncodingCompletedEventArgs FinalizeEncoding(MediaEncoderSettings settings, DateTime? startTime) {
            EncodingCompletedEventArgs Result = null;
            if (File.Exists(settings.OutputFile)) {
                // Muxe video with audio.
                string FinalFile = GetNextAvailableFileName(settings.FinalFile);
                if (!settings.IgnoreAudio)
                    FfmpegBusiness.JoinAudioVideo(settings.OutputFile, Settings.NaturalGroundingFolder + settings.FileName, FinalFile, true);
                else
                    FfmpegBusiness.JoinAudioVideo(settings.OutputFile, null, FinalFile, true);

                Result = GetEncodingResults(settings, FinalFile, startTime);
            }

            return Result;
        }
        private EncodingCompletedEventArgs FinalizeEncoding(MediaEncoderSettings settings, DateTime? startTime) {
            EncodingCompletedEventArgs Result = null;
            if (File.Exists(settings.OutputFile) || (settings.VideoCodec == VideoCodecs.Copy && File.Exists(settings.AudioFileAac))) {
                // Muxe video with audio.
                string FinalFile = GetNextAvailableFileName(settings.FinalFile);
                string VideoFile = null;
                if (settings.VideoCodec == VideoCodecs.Copy)
                    VideoFile = Settings.NaturalGroundingFolder + settings.FileName;
                else
                    VideoFile = settings.OutputFile;
                string AudioFile = null;
                if (settings.AudioAction == AudioActions.Copy)
                    AudioFile = Settings.NaturalGroundingFolder + settings.FileName;
                else if (settings.AudioAction == AudioActions.Encode)
                    AudioFile = settings.AudioFileAac;
                FfmpegBusiness.JoinAudioVideo(VideoFile, AudioFile, FinalFile, true);
                Result = GetEncodingResults(settings, FinalFile, startTime);
            }

            return Result;
        }
 private EncodingCompletedEventArgs EncodeFileThread(MediaEncoderSettings settings) {
     EncodingCompletedEventArgs Result = null;
     DateTime StartTime = DateTime.Now;
     FfmpegBusiness.ConvertToH264(settings.ScriptFile, settings.OutputFile, settings.EncodeQuality);
     Result = FinalizeEncoding(settings, StartTime);
     return Result;
 }
        private async Task WaitEncodeProcessAsync(MediaEncoderSettings settings, Process jobProcess) {
            ProcessingQueue.Add(Path.GetFileNameWithoutExtension(settings.FileName));

            EncodingCompletedEventArgs EncodingResult;
            if (EncoderTask == null)
                EncoderTask = Task.Run(() => {
                    jobProcess.WaitForExit();
                    return FinalizeEncoding(settings, DateTime.Now);
                });
            else
                EncoderTask = EncoderTask.ContinueWith((prevTask) => {
                    jobProcess.WaitForExit();
                    return FinalizeEncoding(settings, DateTime.Now);
                });
            EncodingResult = await EncoderTask;

            ProcessingQueue.RemoveAt(0);
            if (EncodingResult != null && EncodingCompleted != null)
                EncodingCompleted(this, EncodingResult);
        }
        private async Task StartEncodeFileAsync(MediaEncoderSettings settings) {
            ProcessingQueue.Add(Path.GetFileNameWithoutExtension(settings.FileName));

            EncodingCompletedEventArgs EncodingResult;
            if (EncoderTask == null)
                EncoderTask = Task.Run(() => EncodeFileThread(settings));
            else
                EncoderTask = EncoderTask.ContinueWith((prevTask) => EncodeFileThread(settings));
            EncodingResult = await EncoderTask;

            ProcessingQueue.RemoveAt(0);
            if (EncodingResult != null && EncodingCompleted != null)
                EncodingCompleted(this, EncodingResult);
        }
        /// <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);
        }
        private EncodingCompletedEventArgs EncodeFileThread(MediaEncoderSettings settings) {
            EncodingCompletedEventArgs Result = null;
            DateTime StartTime = DateTime.Now;
            Task<bool> VideoEnc = null;
            if (settings.VideoCodec != VideoCodecs.Copy)
                VideoEnc = Task.Run(() => FfmpegBusiness.EncodeH264(settings));

            // Encode audio stream with Nero Aac Encoder
            if (settings.AudioAction == AudioActions.Encode) {
                Task<bool> AudioEnc = Task.Run(() => EncodeAudio(settings));
                if (VideoEnc != null)
                    Task.WaitAll(VideoEnc, AudioEnc);
                else
                    Task.WaitAll(AudioEnc);
            } else if (VideoEnc != null)
                Task.WaitAll(VideoEnc);

            Result = FinalizeEncoding(settings, StartTime);
            return Result;
        }