Example #1
0
        /// <summary>
        /// Calculate max allowed bitrate
        /// </summary>
        /// <param name="x264Prof">Encoding profile</param>
        /// <param name="outType">Target type</param>
        /// <returns>Max allowed bitrate</returns>
        public static int CalculateMaxRatex264(X264Profile x264Prof, OutputType outType)
        {
            int[] baseLineBitrates =
            {
                64,        192, 384, 786, 2000, 4000, 4000, 10000, 14000, 20000, 20000, 50000, 50000,
                135000, 240000, -1
            };

            int[] highBitrates =
            {
                80,        240, 480, 960, 2500, 5000, 5000, 12500, 17500, 25000, 25000, 62500, 62500,
                168750, 300000, -1
            };

            const int maxBlurayBitrate = 40000;

            if (outType == OutputType.OutputBluRay)
            {
                return(maxBlurayBitrate);
            }

            return(x264Prof.AvcProfile < 2 ? baseLineBitrates[x264Prof.AvcLevel] : highBitrates[x264Prof.AvcLevel]);
        }
 public void SetProfile(X264Profile inProfile)
 {
     Profile = inProfile;
 }
Example #3
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 #4
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;
        }