コード例 #1
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;
        }
コード例 #2
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;
        }