Example #1
0
        private int GetTotalEncodingSteps()
        {
            int encodingSteps = 0;

            foreach (EncodeInfo job in JobList)
            {
                if (!string.IsNullOrEmpty(job.TempInput))
                {
                    encodingSteps++; // create temp file with ascii filename
                }
                encodingSteps++;     // demux

                encodingSteps +=
                    job.AudioStreams.Count(
                        aud =>
                        job.AudioProfile.Type == ProfileType.AC3 || job.AudioProfile.Type == ProfileType.OGG ||
                        job.AudioProfile.Type == ProfileType.MP3 || job.AudioProfile.Type == ProfileType.AAC ||
                        job.AudioProfile.Type == ProfileType.FLAC);

                // demux subtitles
                encodingSteps += job.SubtitleStreams.Count(sub => sub.RawStream == false);

                // process subtitles
                encodingSteps += job.SubtitleStreams.Count(sub => sub.NeedConversion);

                if (job.VideoStream != null)
                {
                    if (job.VideoProfile.Type != ProfileType.Copy)
                    {
                        encodingSteps++;   // index
                        switch (job.VideoProfile.Type)
                        {
                        case ProfileType.X264:
                            X264Profile videoProfile = (X264Profile)job.VideoProfile;

                            switch (videoProfile.EncodingMode)
                            {
                            case 2:
                                encodingSteps += 2;             // 2 pass encoding
                                break;

                            case 3:
                                encodingSteps += 3;             // 3 pass encoding
                                break;

                            default:
                                encodingSteps++;
                                break;
                            }

                            if (job.EncodingProfile.AutoCropResize && !job.EncodingProfile.KeepInputResolution)
                            {
                                encodingSteps++;        // search croprect
                            }
                            break;

                        case ProfileType.HcEnc:
                            encodingSteps += 2;
                            break;

                        case ProfileType.VP8:
                            VP8Profile vp8Profile = (VP8Profile)job.VideoProfile;
                            if (vp8Profile.EncodingMode == 0)
                            {
                                encodingSteps++;
                            }
                            else
                            {
                                encodingSteps += 2;
                            }

                            if (job.EncodingProfile.AutoCropResize && !job.EncodingProfile.KeepInputResolution)
                            {
                                encodingSteps++;        // search croprect
                            }
                            break;
                        }
                    } // end if videoprofile != copy

                    if (job.EncodingProfile.OutFormat == OutputType.OutputDvd)
                    {
                        encodingSteps++;   // premux streams for dvdauthor
                        if (job.SubtitleStreams.Count > 0)
                        {
                            encodingSteps += job.SubtitleStreams.Count;    // premux subtitles
                        }
                    }
                } // end if videostream != null

                encodingSteps++;    // mux streams

                if (!string.IsNullOrEmpty(job.TempOutput))
                {
                    encodingSteps++; // move finished file to output destination
                }
                if (AppSettings.CreateXbmcInfoFile && (job.MovieInfo != null || job.EpisodeInfo != null))
                {
                    encodingSteps++; // create xbmc info files
                }
            }                        // foreach job

            return(encodingSteps);
        }
Example #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;
        }
Example #3
0
        /// <summary>
        /// Generates commandline arguments used for encoding an video stream to VP8 format.
        /// Input is always stdin.
        /// </summary>
        /// <param name="inProfile">Encoding profile</param>
        /// <param name="bitrate">Target bitrate</param>
        /// <param name="hRes">Video width</param>
        /// <param name="vRes">Video height</param>
        /// <param name="pass">Encoding pass</param>
        /// <param name="fpsN">Framerate numerator</param>
        /// <param name="fpsD">Framerate denominator</param>
        /// <param name="outFile">Path to output file</param>
        /// <returns>Commandline arguments</returns>
        public static string Generate(VP8Profile inProfile, int bitrate, int hRes, int vRes, int pass, int fpsN, int fpsD,
                                      string outFile = "output")
        {
            StringBuilder sb = new StringBuilder();

            if (inProfile != null)
            {
                int tempPass = pass;

                sb.Append("--debug --codec=");
                sb.Append(inProfile.Encoder == 0 ? "vp8 " : "vp9 ");

                sb.AppendFormat(AppSettings.CInfo, "--width={0:g} --height={1:g} ", hRes, vRes);

                sb.AppendFormat(AppSettings.CInfo, " --deadline={0:g} ", inProfile.DeadlinePerFrame);

                sb.Append("--passes=");
                switch (inProfile.EncodingMode)
                {
                case 0:
                    sb.Append("1 ");
                    break;

                case 1:
                    sb.Append("2 ");
                    sb.AppendFormat(AppSettings.CInfo, "--pass={0:g} ", tempPass);
                    break;
                }

                int tempBitrate = bitrate;
                if (tempBitrate <= 0)
                {
                    tempBitrate = inProfile.Bitrate;
                }
                sb.AppendFormat(AppSettings.CInfo, "--target-bitrate={0:g} ", tempBitrate);

                sb.AppendFormat(AppSettings.CInfo, "--end-usage={0:g} ", inProfile.BitrateMode);

                if (inProfile.EncodingMode == 1)
                {
                    string fpfFile = Processing.CreateTempFile(outFile, "stats");
                    sb.AppendFormat("--fpf=\"{0}\" ", fpfFile);
                }

                sb.AppendFormat(AppSettings.CInfo, "--profile={0:g} ", inProfile.Profile);

                switch (inProfile.SpeedControl)
                {
                case 0:
                    sb.Append("--rt ");
                    break;

                case 1:
                    sb.Append("--good ");
                    break;

                case 2:
                    sb.Append("--best ");
                    break;
                }

                sb.AppendFormat(AppSettings.CInfo, "--cpu-used={0:g} ", inProfile.CPUModifier);
                sb.AppendFormat(AppSettings.CInfo, "--token-parts={0:g} ", inProfile.TokenPart);
                sb.AppendFormat(AppSettings.CInfo, "--noise-sensitivity={0:g} ", inProfile.NoiseFiltering);
                sb.AppendFormat(AppSettings.CInfo, "--sharpness={0:g} ", inProfile.Sharpness);

                int tempThreads = inProfile.Threads;
                if (tempThreads == 0)
                {
                    tempThreads = Environment.ProcessorCount * 2;
                }
                sb.AppendFormat(AppSettings.CInfo, "--threads={0:g} ", tempThreads);

                sb.AppendFormat(AppSettings.CInfo, "--static-thresh={0:g} ", inProfile.StaticThreshold);

                sb.Append("--error-resilient=");
                sb.Append(inProfile.UseErrorResilience ? "1 " : "0 ");

                sb.AppendFormat(AppSettings.CInfo, "--kf-min-dist={0:g} --kf-max-dist={1:g} ",
                                inProfile.GopMin, inProfile.GopMax);

                sb.AppendFormat(AppSettings.CInfo, "--lag-in-frames={0:g} ", inProfile.MaxFramesLag);
                sb.AppendFormat(AppSettings.CInfo, "--drop-frame={0:g} ", inProfile.FrameDrop);

                if (inProfile.UseSpatialResampling)
                {
                    sb.AppendFormat(AppSettings.CInfo, "--resize-allowed=1 --resize-up={0:g} --resize-down={1:g} ",
                                    inProfile.UpscaleThreshold, inProfile.DownscaleThreshold);
                }
                else
                {
                    sb.Append("--resize-allowed=0 ");
                }

                if (inProfile.UseArnrFrameDecision)
                {
                    sb.AppendFormat(AppSettings.CInfo, "--auto-alt-ref=1 --arnr-maxframes={0:g} --arnr-strength={1:g} ",
                                    inProfile.ArnrMaxFrames, inProfile.ArnrStrength);
                }
                else
                {
                    sb.Append("--auto-alt-ref=0 ");
                }

                sb.AppendFormat(AppSettings.CInfo, "--buf-initial-sz={0:g} ", inProfile.InitialBufferSize);
                sb.AppendFormat(AppSettings.CInfo, "--buf-optimal-sz={0:g} ", inProfile.OptimalBufferSize);
                sb.AppendFormat(AppSettings.CInfo, "--buf-sz={0:g} ", inProfile.BufferSize);
                sb.AppendFormat(AppSettings.CInfo, "--undershoot-pct={0:g} ", inProfile.UndershootDataRate);

                sb.AppendFormat(AppSettings.CInfo, "--min-q={0:g} --max-q={1:g} ",
                                inProfile.QuantizerMin, inProfile.QuantizerMax);

                sb.AppendFormat(AppSettings.CInfo, "--bias-pct={0:g} ", inProfile.BiasFrameAdjust);
                sb.AppendFormat(AppSettings.CInfo, "--minsection-pct={0:g} --maxsection-pct={1:g} ",
                                inProfile.SectionMin, inProfile.SectionMax);

                // in 2-pass encoding mode use null output for first pass
                if (inProfile.EncodingMode == 1 && tempPass == 1)
                {
                    sb.Append("-o NUL ");
                }
                else if (!String.IsNullOrEmpty(outFile))
                {
                    sb.AppendFormat("-o \"{0}\" ", outFile);
                }

                sb.Append("- ");
            }
            return(sb.ToString());
        }