/// <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; }
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); }
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; }