public void DoEncodeDvd(object sender, DoWorkEventArgs e) { _bw = (BackgroundWorker)sender; string status = Processing.GetResourceString("hcenc_encoding_status"); string progressFmt = Processing.GetResourceString("hcenc_encoding_progress"); _bw.ReportProgress(-10, status); _bw.ReportProgress(0, status); string inputFile = _jobInfo.VideoStream.TempFile; string outFile = Processing.CreateTempFile(inputFile, "encoded.m2v"); _jobInfo.AviSynthScript = GenerateAviSynthFile(); string localExecutable = Path.Combine(AppSettings.ToolsPath, Executable); using (Process encoder = new Process()) { ProcessStartInfo encoderParameter = new ProcessStartInfo(localExecutable) { WorkingDirectory = AppSettings.DemuxLocation }; float sourceAspect = (float)Math.Round(_jobInfo.VideoStream.AspectRatio, 3); int targetAspect = sourceAspect >= 1.4f ? 1 : 0; int bitrate = 0; if (_jobInfo.EncodingProfile.TargetFileSize > 1) { bitrate = Processing.CalculateVideoBitrate(_jobInfo); } int audBitrate = _jobInfo.AudioStreams.Sum(stream => (int)stream.Bitrate / 1000); int maxRate = 9800 - audBitrate; string iniFile = HcencCommandLineGenerator.Generate((HcEncProfile)_jobInfo.VideoProfile, _jobInfo.AviSynthScript, outFile, targetAspect, bitrate, maxRate); encoderParameter.Arguments = string.Format("-ini \"{0}\" ", iniFile); encoderParameter.UseShellExecute = true; encoderParameter.WindowStyle = ProcessWindowStyle.Minimized; encoder.StartInfo = encoderParameter; Log.InfoFormat("hcenc {0:s}", encoderParameter.Arguments); bool encstarted; try { encstarted = encoder.Start(); } catch (Exception ex) { encstarted = false; Log.ErrorFormat("hcenc exception: {0}", ex); _jobInfo.ExitCode = -1; } DateTime startTime = DateTime.Now; TimeSpan remaining = new TimeSpan(0, 0, 0); if (encstarted) { encoder.PriorityClass = AppSettings.GetProcessPriority(); encoder.WaitForInputIdle(2500); SystemWindow mainWin = new SystemWindow(encoder.MainWindowHandle) { VisibilityFlag = false }; SystemWindow processedFrames = FindWindowByDialogId(1028, mainWin.AllChildWindows); SystemWindow averageFps = FindWindowByDialogId(1061, mainWin.AllChildWindows); SystemWindow pass = FindWindowByDialogId(1013, mainWin.AllChildWindows); SystemWindow info = FindWindowByDialogId(1053, mainWin.AllChildWindows); SystemWindow currProgress = FindWindowByDialogId(1065, mainWin.AllChildWindows); string lastInfo = string.Empty; while (!encoder.HasExited) { if (_bw.CancellationPending) { encoder.Kill(); } else { try { Regex regObj = new Regex(@"^.*?([\d]*?)%\s*?HCenc.*$", RegexOptions.Singleline | RegexOptions.Multiline); Match result = regObj.Match(mainWin.Title); if (result.Success) { int overallProgress; Int32.TryParse(result.Groups[1].Value, NumberStyles.Number, AppSettings.CInfo, out overallProgress); double codingFps; Double.TryParse(averageFps.Content.ShortDescription, NumberStyles.Number, AppSettings.CInfo, out codingFps); int currentProgress; Int32.TryParse(currProgress.Content.ShortDescription.TrimEnd('%'), NumberStyles.Number, AppSettings.CInfo, out currentProgress); int frame; Int32.TryParse(processedFrames.Content.ShortDescription, NumberStyles.Number, AppSettings.CInfo, out frame); if (info.Content.ShortDescription != lastInfo) { lastInfo = info.Content.ShortDescription; Log.InfoFormat("hcenc: {0:s}", lastInfo); } DateTime now = DateTime.Now; TimeSpan eta = now.Subtract(startTime); int percentRemain = 100 - overallProgress; double secRemaining = 0d; if (eta.Seconds != 0) { double speed = Math.Round(overallProgress / eta.TotalSeconds, 6); if (speed > 0f) { secRemaining = percentRemain / speed; } else { secRemaining = 0; } } if (secRemaining > 0) { remaining = new TimeSpan(0, 0, (int)secRemaining); } DateTime ticks1 = new DateTime(eta.Ticks); string progress = string.Format(progressFmt, frame, codingFps, pass.Content.ShortDescription, currentProgress, ticks1, remaining); _bw.ReportProgress(overallProgress, progress); } } catch (Exception exception) { Log.ErrorFormat("hcEnc Exception {0}", exception.Message); } } Thread.Sleep(500); } encoder.WaitForExit(10000); _jobInfo.ExitCode = encoder.ExitCode; Log.InfoFormat("Exit Code: {0:g}", _jobInfo.ExitCode); if (_jobInfo.ExitCode == 0) { _jobInfo.VideoStream.IsRawStream = false; _jobInfo.VideoStream.Encoded = true; _jobInfo.TempFiles.Add(inputFile); _jobInfo.VideoStream.TempFile = outFile; _jobInfo.TempFiles.Add(_jobInfo.AviSynthScript); _jobInfo.TempFiles.Add(iniFile); try { _jobInfo.MediaInfo = Processing.GetMediaInfo(_jobInfo.VideoStream.TempFile); } catch (TimeoutException ex) { Log.Error(ex); } _jobInfo.VideoStream = VideoHelper.GetStreamInfo(_jobInfo.MediaInfo, _jobInfo.VideoStream, _jobInfo.EncodingProfile.OutFormat == OutputType.OutputBluRay); _jobInfo.TempFiles.Add(Path.Combine(AppSettings.DemuxLocation, "HC01.lls")); _jobInfo.TempFiles.Add(_jobInfo.FfIndexFile); } } } _bw.ReportProgress(100); _jobInfo.CompletedStep = _jobInfo.NextStep; e.Result = _jobInfo; }
public void DoEncode(object sender, DoWorkEventArgs e) { _bw = (BackgroundWorker)sender; string passStr = Processing.GetResourceString("vp8_pass"); string status = Processing.GetResourceString("vp8_encoding_status"); VP8Profile encProfile = (VP8Profile)_jobInfo.VideoProfile; if (!_jobInfo.EncodingProfile.Deinterlace && _jobInfo.VideoStream.Interlaced) { _jobInfo.VideoStream.Interlaced = false; } Size resizeTo = VideoHelper.GetTargetSize(_jobInfo); if (string.IsNullOrEmpty(_jobInfo.AviSynthScript)) { GenerateAviSynthScript(resizeTo); } string inputFile = _jobInfo.AviSynthScript; string outFile = Processing.CreateTempFile( string.IsNullOrEmpty(_jobInfo.TempOutput) ? _jobInfo.BaseName : _jobInfo.TempOutput, "encoded.webm"); _frameCount = _jobInfo.VideoStream.FrameCount; int targetBitrate = 0; if (_jobInfo.EncodingProfile.TargetFileSize > 0) { targetBitrate = Processing.CalculateVideoBitrate(_jobInfo); } int encodeMode = encProfile.EncodingMode; if (encodeMode == 1) { _pass = string.Format(" {1} {0:0}; ", _jobInfo.StreamId, passStr); } _bw.ReportProgress(-10, status + _pass.Replace("; ", string.Empty)); _bw.ReportProgress(0, status); string argument = VP8CommandLineGenerator.Generate(encProfile, targetBitrate, resizeTo.Width, resizeTo.Height, _jobInfo.StreamId, _jobInfo.VideoStream.FrameRateEnumerator, _jobInfo.VideoStream.FrameRateDenominator, outFile); string localExecutable = Path.Combine(AppSettings.ToolsPath, Executable); using (Process encoder = new Process(), decoder = FfMpeg.GenerateDecodeProcess(inputFile, AppSettings.Use64BitEncoders && AppSettings.UseFfmpegScaling, new Size(_jobInfo.VideoStream.Width, _jobInfo.VideoStream.Height), _jobInfo.VideoStream.AspectRatio, _jobInfo.VideoStream.CropRect, resizeTo)) { ProcessStartInfo parameter = new ProcessStartInfo(localExecutable) { WorkingDirectory = AppSettings.DemuxLocation, Arguments = argument, CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true, RedirectStandardInput = true }; encoder.StartInfo = parameter; encoder.ErrorDataReceived += OnDataReceived; Log.InfoFormat("start parameter: vpxenc {0:s}", argument); bool started; bool decStarted; try { started = encoder.Start(); } catch (Exception ex) { started = false; Log.ErrorFormat("vpxenc exception: {0}", ex); _jobInfo.ExitCode = -1; } NamedPipeServerStream decodePipe = new NamedPipeServerStream(AppSettings.DecodeNamedPipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.None); try { decStarted = decoder.Start(); } catch (Exception ex) { decStarted = false; Log.ErrorFormat("avconv exception: {0}", ex); _jobInfo.ExitCode = -1; } _startTime = DateTime.Now; if (started && decStarted) { encoder.PriorityClass = AppSettings.GetProcessPriority(); encoder.BeginErrorReadLine(); decoder.PriorityClass = AppSettings.GetProcessPriority(); decoder.BeginErrorReadLine(); Thread pipeReadThread = new Thread(() => { try { ReadThreadStart(decodePipe, encoder); } catch (Exception ex) { Log.Error(ex); } }); pipeReadThread.Start(); pipeReadThread.Priority = ThreadPriority.BelowNormal; encoder.Exited += (o, args) => pipeReadThread.Abort(); while (!encoder.HasExited) { if (_bw.CancellationPending) { encoder.Kill(); decoder.Kill(); } Thread.Sleep(200); } encoder.WaitForExit(10000); encoder.CancelErrorRead(); if (decodePipe.IsConnected) { try { decodePipe.Disconnect(); } catch (Exception ex) { Log.Error(ex); } } try { decodePipe.Close(); decodePipe.Dispose(); } catch (Exception ex) { Log.Error(ex); } decoder.WaitForExit(10000); decoder.CancelErrorRead(); _jobInfo.ExitCode = encoder.ExitCode; Log.InfoFormat("Exit Code: {0:g}", _jobInfo.ExitCode); } } if (_jobInfo.ExitCode == 0) { if ((encProfile.EncodingMode == 1 && _jobInfo.StreamId == 2) || encProfile.EncodingMode == 0) { _jobInfo.VideoStream.Encoded = true; _jobInfo.VideoStream.IsRawStream = false; _jobInfo.TempFiles.Add(_jobInfo.VideoStream.TempFile); _jobInfo.VideoStream.TempFile = outFile; try { _jobInfo.MediaInfo = Processing.GetMediaInfo(_jobInfo.VideoStream.TempFile); } catch (TimeoutException ex) { Log.Error(ex); } _jobInfo.VideoStream = VideoHelper.GetStreamInfo(_jobInfo.MediaInfo, _jobInfo.VideoStream, _jobInfo.EncodingProfile.OutFormat == OutputType.OutputBluRay); string statsFile = Processing.CreateTempFile(outFile, "stats"); _jobInfo.TempFiles.Add(statsFile); _jobInfo.TempFiles.Add(_jobInfo.AviSynthScript); _jobInfo.TempFiles.Add(_jobInfo.FfIndexFile); _jobInfo.TempFiles.Add(_jobInfo.AviSynthStereoConfig); } } _bw.ReportProgress(100); _jobInfo.CompletedStep = _jobInfo.NextStep; e.Result = _jobInfo; }
public void DoEncode(object sender, DoWorkEventArgs e) { _bw = (BackgroundWorker)sender; string passStr = Processing.GetResourceString("x264_pass"); string status = Processing.GetResourceString("x264_encoding_status"); bool use64BitEncoder = AppSettings.Use64BitEncoders && AppSettings.X26464Installed && Environment.Is64BitOperatingSystem; X264Profile encProfile = (X264Profile)_jobInfo.VideoProfile; if (!_jobInfo.EncodingProfile.Deinterlace && _jobInfo.VideoStream.Interlaced) { _jobInfo.VideoStream.Interlaced = false; } Size resizeTo = VideoHelper.GetTargetSize(_jobInfo); if (string.IsNullOrEmpty(_jobInfo.AviSynthScript)) { GenerateAviSynthScript(resizeTo); } string inputFile = _jobInfo.AviSynthScript; string outFile = Processing.CreateTempFile( string.IsNullOrEmpty(_jobInfo.TempOutput) ? _jobInfo.BaseName : _jobInfo.TempOutput, "encoded.264"); int targetBitrate = 0; if (_jobInfo.EncodingProfile.TargetFileSize > 0) { targetBitrate = Processing.CalculateVideoBitrate(_jobInfo); } int encodeMode = encProfile.EncodingMode; if ((encodeMode == 2) || (encodeMode == 3)) { _pass = string.Format(" {1} {0:0}; ", _jobInfo.StreamId, passStr); } _frameCount = _jobInfo.VideoStream.FrameCount; _bw.ReportProgress(-10, status + _pass.Replace("; ", string.Empty)); _bw.ReportProgress(0, status); string argument = X264CommandLineGenerator.Generate(encProfile, targetBitrate, resizeTo.Width, resizeTo.Height, _jobInfo.StreamId, _jobInfo.VideoStream.FrameRateEnumerator, _jobInfo.VideoStream.FrameRateDenominator, _jobInfo.EncodingProfile.StereoType, _jobInfo.VideoStream.PicSize, // check if we use 64 bit version //use64BitEncoder ? "-" : inputFile, "-", outFile); string localExecutable = Path.Combine(AppSettings.ToolsPath, use64BitEncoder ? Executable64 : Executable); using (Process encoder = new Process()) { ProcessStartInfo parameter = new ProcessStartInfo(localExecutable) { WorkingDirectory = AppSettings.DemuxLocation, Arguments = argument, CreateNoWindow = true, UseShellExecute = false, RedirectStandardError = true, RedirectStandardInput = use64BitEncoder }; encoder.StartInfo = parameter; encoder.ErrorDataReceived += OnDataReceived; Log.InfoFormat("start parameter: x264 {0:s}", argument); bool started; bool decStarted; NamedPipeServerStream decodePipe = new NamedPipeServerStream(AppSettings.DecodeNamedPipeName, PipeDirection.InOut, 3, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); decodePipe.BeginWaitForConnection(DecoderConnected, null); Size originalSize = new Size(_jobInfo.VideoStream.Width, _jobInfo.VideoStream.Height); if (_jobInfo.VideoStream.Width < _jobInfo.VideoStream.Height * _jobInfo.VideoStream.AspectRatio) { originalSize.Width = (int)(_jobInfo.VideoStream.Height * _jobInfo.VideoStream.AspectRatio); int temp; Math.DivRem(originalSize.Width, 2, out temp); originalSize.Width += temp; } Process decoder = FfMpeg.GenerateDecodeProcess(inputFile, AppSettings.Use64BitEncoders && AppSettings.UseFfmpegScaling, originalSize, _jobInfo.VideoStream.AspectRatio, _jobInfo.VideoStream.CropRect, resizeTo); try { decStarted = decoder.Start(); } catch (Exception ex) { decStarted = false; Log.ErrorFormat("avconv exception: {0}", ex); _jobInfo.ExitCode = -1; } try { started = encoder.Start(); } catch (Exception ex) { started = false; Log.ErrorFormat("x264 encoder exception: {0}", ex); _jobInfo.ExitCode = -1; } _startTime = DateTime.Now; if (started && decStarted) { encoder.PriorityClass = AppSettings.GetProcessPriority(); encoder.BeginErrorReadLine(); decoder.PriorityClass = AppSettings.GetProcessPriority(); decoder.BeginErrorReadLine(); Thread pipeReadThread = new Thread(() => { try { if (encoder != null) { ReadThreadStart(decodePipe, encoder); } } catch (Exception ex) { Log.Error(ex); } }); pipeReadThread.Start(); pipeReadThread.Priority = ThreadPriority.BelowNormal; decoder.Exited += (o, args) => { try { decodePipe.Disconnect(); decodePipe.Close(); decodePipe.Dispose(); } catch (Exception ex) { Log.Error(ex); } }; encoder.Exited += (o, args) => pipeReadThread.Abort(); while (!encoder.HasExited && !decoder.HasExited) { if (_bw.CancellationPending) { encoder.Kill(); decoder.Kill(); } Thread.Sleep(200); } encoder.WaitForExit(10000); encoder.CancelErrorRead(); decoder.WaitForExit(10000); decoder.CancelErrorRead(); _jobInfo.ExitCode = encoder.ExitCode; Log.InfoFormat("Exit Code: {0:g}", _jobInfo.ExitCode); } } if (_jobInfo.ExitCode == 0) { if ((encProfile.EncodingMode == 2 && _jobInfo.StreamId == 2) || (encProfile.EncodingMode == 3 && _jobInfo.StreamId == 3) || (encProfile.EncodingMode < 2 || _jobInfo.StreamId > 3)) { _jobInfo.VideoStream.Encoded = true; _jobInfo.VideoStream.IsRawStream = true; _jobInfo.TempFiles.Add(_jobInfo.VideoStream.TempFile); _jobInfo.VideoStream.TempFile = outFile; try { _jobInfo.MediaInfo = Processing.GetMediaInfo(_jobInfo.VideoStream.TempFile); } catch (TimeoutException ex) { Log.Error(ex); } _jobInfo.VideoStream = VideoHelper.GetStreamInfo(_jobInfo.MediaInfo, _jobInfo.VideoStream, _jobInfo.EncodingProfile.OutFormat == OutputType.OutputBluRay); _jobInfo.TempFiles.Add(Path.Combine(AppSettings.DemuxLocation, "x264_2pass.log")); _jobInfo.TempFiles.Add(Path.Combine(AppSettings.DemuxLocation, "x264_2pass.log.mbtree")); _jobInfo.TempFiles.Add(_jobInfo.AviSynthScript); _jobInfo.TempFiles.Add(_jobInfo.FfIndexFile); _jobInfo.TempFiles.Add(_jobInfo.AviSynthStereoConfig); } } _bw.ReportProgress(100); _jobInfo.CompletedStep = _jobInfo.NextStep; e.Result = _jobInfo; }