Пример #1
0
        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;
        }
Пример #2
0
        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;
        }
Пример #3
0
        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;
        }