public JobChain GenerateJobSeries(VideoStream video, string muxedOutput, AudioJob[] audioStreams, MuxStream[] subtitles, string chapters, FileSize?desiredSize, FileSize?splitSize, ContainerType container, bool prerender, MuxStream[] muxOnlyAudio) { StringBuilder logBuilder = new StringBuilder(); if (desiredSize.HasValue) { logBuilder.Append("Generating jobs. Desired size: " + desiredSize.Value.ToString() + "\r\n"); if (video.Settings.EncodingMode != 4 && video.Settings.EncodingMode != 8) // no automated 2/3 pass { if (this.mainForm.Settings.NbPasses == 2) { video.Settings.EncodingMode = 4; // automated 2 pass } else if (video.Settings.MaxNumberOfPasses == 3) { video.Settings.EncodingMode = 8; } } } else { logBuilder.Append("Generating jobs. No desired size.\r\n"); } fixFileNameExtensions(video, audioStreams, container); string videoOutput = video.Output; logBuilder.Append(eliminatedDuplicateFilenames(ref videoOutput, ref muxedOutput, audioStreams)); video.Output = videoOutput; JobChain vjobs = jobUtil.prepareVideoJob(video.Input, video.Output, video.Settings, video.DAR, prerender, true); if (vjobs == null) { return(null); } /* Here, we guess the types of the files based on extension. * This is guaranteed to work with MeGUI-encoded files, because * the extension will always be recognised. For non-MeGUI files, * we can only ever hope.*/ List <MuxStream> allAudioToMux = new List <MuxStream>(); List <MuxableType> allInputAudioTypes = new List <MuxableType>(); foreach (MuxStream muxStream in muxOnlyAudio) { if (VideoUtil.guessAudioMuxableType(muxStream.path, true) != null) { allInputAudioTypes.Add(VideoUtil.guessAudioMuxableType(muxStream.path, true)); allAudioToMux.Add(muxStream); } } foreach (AudioJob stream in audioStreams) { allAudioToMux.Add(stream.ToMuxStream()); allInputAudioTypes.Add(stream.ToMuxableType()); } List <MuxableType> allInputSubtitleTypes = new List <MuxableType>(); foreach (MuxStream muxStream in subtitles) { if (VideoUtil.guessSubtitleType(muxStream.path) != null) { allInputSubtitleTypes.Add(new MuxableType(VideoUtil.guessSubtitleType(muxStream.path), null)); } } MuxableType chapterInputType = null; if (!String.IsNullOrEmpty(chapters)) { ChapterType type = VideoUtil.guessChapterType(chapters); if (type != null) { chapterInputType = new MuxableType(type, null); } } JobChain muxJobs = this.jobUtil.GenerateMuxJobs(video, video.Framerate, allAudioToMux.ToArray(), allInputAudioTypes.ToArray(), subtitles, allInputSubtitleTypes.ToArray(), chapters, chapterInputType, container, muxedOutput, splitSize, true); /* foreach (Job mJob in muxJobs) * foreach (Job job in jobs) * mJob.AddDependency(job);*/ /* * foreach (VideoJob job in vjobs) * { * jobs.Add(job); * } * foreach (MuxJob job in muxJobs) * { * jobs.Add(job); * } */ if (desiredSize.HasValue) { /* if (encodedAudioPresent) // no audio encoding, we can calculate the video bitrate directly * { * logBuilder.Append("No audio encoding. Calculating desired video bitrate directly.\r\n"); * List<AudioStream> calculationAudioStreams = new List<AudioStream>(); * foreach (SubStream stream in muxOnlyAudio) * { * FileInfo fi = new FileInfo(stream.path); * AudioStream newStream = new AudioStream(); * newStream.SizeBytes = fi.Length; * newStream.Type = guessAudioType(stream.path); * newStream.BitrateMode = BitrateManagementMode.VBR; * calculationAudioStreams.Add(newStream); * logBuilder.Append("Encoded audio file is present: " + stream.path + * " It has a size of " + fi.Length + " bytes. \r\n"); * } * * long videoSizeKB; * bool useBframes = false; * if (video.Settings.NbBframes > 0) * useBframes = true; * * bitrateKBits = calc.CalculateBitrateKBits(video.Settings.Codec, useBframes, container, calculationAudioStreams.ToArray(), * desiredSizeBytes, video.NumberOfFrames, video.Framerate, out videoSizeKB); * desiredSizeBytes = (long)videoSizeKB * 1024L; // convert kb back to bytes * logBuilder.Append("Setting video bitrate for the video jobs to " + bitrateKBits + " kbit/s\r\n"); * foreach (VideoJob vJob in vjobs) * { * jobUtil.updateVideoBitrate(vJob, bitrateKBits); * } * }*/ BitrateCalculationInfo b = new BitrateCalculationInfo(); List <string> audiofiles = new List <string>(); foreach (MuxStream s in allAudioToMux) { audiofiles.Add(s.path); } b.AudioFiles = audiofiles; b.Container = container; b.VideoJobs = new List <TaggedJob>(vjobs.Jobs); b.DesiredSize = desiredSize.Value; ((VideoJob)vjobs.Jobs[0].Job).BitrateCalculationInfo = b; } mainForm.addToLog(logBuilder.ToString()); return (new SequentialChain( new ParallelChain((Job[])audioStreams), new SequentialChain(vjobs), new SequentialChain(muxJobs))); }
public JobChain GenerateJobSeries(VideoStream video, string muxedOutput, AudioJob[] audioStreams, MuxStream[] subtitles, string chapters, FileSize?desiredSize, FileSize?splitSize, ContainerType container, bool prerender, MuxStream[] muxOnlyAudio, LogItem log, string deviceType, Zone[] zones, string videoFileToMux, OneClickAudioTrack[] audioTracks) { if (desiredSize.HasValue && String.IsNullOrEmpty(videoFileToMux)) { if (video.Settings.EncodingMode != 4 && video.Settings.EncodingMode != 8) // no automated 2/3 pass { if (this.mainForm.Settings.NbPasses == 2) { video.Settings.EncodingMode = 4; // automated 2 pass } else if (video.Settings.MaxNumberOfPasses == 3) { video.Settings.EncodingMode = 8; } } } fixFileNameExtensions(video, audioStreams, container); string videoOutput = video.Output; log.Add(eliminatedDuplicateFilenames(ref videoOutput, ref muxedOutput, audioStreams)); JobChain vjobs = null; if (!String.IsNullOrEmpty(videoFileToMux)) { video.Output = videoFileToMux; } else { video.Output = videoOutput; vjobs = jobUtil.prepareVideoJob(video.Input, video.Output, video.Settings, video.DAR, prerender, true, zones); if (vjobs == null) { return(null); } } /* Here, we guess the types of the files based on extension. * This is guaranteed to work with MeGUI-encoded files, because * the extension will always be recognised. For non-MeGUI files, * we can only ever hope.*/ List <MuxStream> allAudioToMux = new List <MuxStream>(); List <MuxableType> allInputAudioTypes = new List <MuxableType>(); if (audioTracks != null) { // OneClick mode foreach (OneClickAudioTrack ocAudioTrack in audioTracks) { if (ocAudioTrack.DirectMuxAudio != null) { if (VideoUtil.guessAudioMuxableType(ocAudioTrack.DirectMuxAudio.path, true) != null) { allInputAudioTypes.Add(VideoUtil.guessAudioMuxableType(ocAudioTrack.DirectMuxAudio.path, true)); allAudioToMux.Add(ocAudioTrack.DirectMuxAudio); } } if (ocAudioTrack.AudioJob != null) { allAudioToMux.Add(ocAudioTrack.AudioJob.ToMuxStream()); allInputAudioTypes.Add(ocAudioTrack.AudioJob.ToMuxableType()); } } } else { // AutoEncode mode foreach (AudioJob stream in audioStreams) { allAudioToMux.Add(stream.ToMuxStream()); allInputAudioTypes.Add(stream.ToMuxableType()); } foreach (MuxStream muxStream in muxOnlyAudio) { if (VideoUtil.guessAudioMuxableType(muxStream.path, true) != null) { allInputAudioTypes.Add(VideoUtil.guessAudioMuxableType(muxStream.path, true)); allAudioToMux.Add(muxStream); } } } List <MuxableType> allInputSubtitleTypes = new List <MuxableType>(); foreach (MuxStream muxStream in subtitles) { if (VideoUtil.guessSubtitleType(muxStream.path) != null) { allInputSubtitleTypes.Add(new MuxableType(VideoUtil.guessSubtitleType(muxStream.path), null)); } } MuxableType chapterInputType = null; if (!String.IsNullOrEmpty(chapters)) { ChapterType type = VideoUtil.guessChapterType(chapters); if (type != null) { chapterInputType = new MuxableType(type, null); } } MuxableType deviceOutputType = null; if (!String.IsNullOrEmpty(deviceType)) { DeviceType type = VideoUtil.guessDeviceType(deviceType); if (type != null) { deviceOutputType = new MuxableType(type, null); } } List <string> inputsToDelete = new List <string>(); if (String.IsNullOrEmpty(videoFileToMux)) { inputsToDelete.Add(video.Output); } inputsToDelete.AddRange(Array.ConvertAll <AudioJob, string>(audioStreams, delegate(AudioJob a) { return(a.Output); })); JobChain muxJobs = jobUtil.GenerateMuxJobs(video, video.Framerate, allAudioToMux.ToArray(), allInputAudioTypes.ToArray(), subtitles, allInputSubtitleTypes.ToArray(), chapters, chapterInputType, container, muxedOutput, splitSize, inputsToDelete, deviceType, deviceOutputType); if (desiredSize.HasValue && String.IsNullOrEmpty(videoFileToMux)) { BitrateCalculationInfo b = new BitrateCalculationInfo(); List <string> audiofiles = new List <string>(); foreach (MuxStream s in allAudioToMux) { audiofiles.Add(s.path); } b.AudioFiles = audiofiles; b.Container = container; b.VideoJobs = new List <TaggedJob>(vjobs.Jobs); b.DesiredSize = desiredSize.Value; ((VideoJob)vjobs.Jobs[0].Job).BitrateCalculationInfo = b; } if (!String.IsNullOrEmpty(videoFileToMux)) { return(new SequentialChain(new SequentialChain((Job[])audioStreams), new SequentialChain(muxJobs))); } else { return(new SequentialChain( new SequentialChain((Job[])audioStreams), new SequentialChain(vjobs), new SequentialChain(muxJobs))); } }