/// <summary> /// Applies an audio encoding to a native audio encoding base structure. /// </summary> /// <param name="encoding">The encoding to apply.</param> /// <param name="baseStruct">The base native structure.</param> /// <param name="outputTrack">The output track number (0-based).</param> /// <param name="allocatedMemory">The collection of allocated memory.</param> /// <returns>The resulting native audio structure.</returns> private hb_audio_s ConvertAudioBack(AudioEncoding encoding, hb_audio_s baseStruct, int outputTrack, List<IntPtr> allocatedMemory) { hb_audio_s nativeAudio = baseStruct; HBAudioEncoder encoder = Encoders.GetAudioEncoder(encoding.Encoder); nativeAudio.config.output.track = outputTrack; nativeAudio.config.output.codec = (uint)encoder.Id; if (!encoder.IsPassthrough) { if (encoding.SampleRateRaw == 0) { nativeAudio.config.output.samplerate = nativeAudio.config.input.samplerate; } else { nativeAudio.config.output.samplerate = encoding.SampleRateRaw; } HBMixdown mixdown = Encoders.GetMixdown(encoding.Mixdown); nativeAudio.config.output.mixdown = mixdown.Id; if (encoding.EncodeRateType == AudioEncodeRateType.Bitrate) { // Disable quality targeting. nativeAudio.config.output.quality = -1; if (encoding.Bitrate == 0) { // Bitrate of 0 means auto: choose the default for this codec, sample rate and mixdown. nativeAudio.config.output.bitrate = HBFunctions.hb_get_default_audio_bitrate( nativeAudio.config.output.codec, nativeAudio.config.output.samplerate, nativeAudio.config.output.mixdown); } else { nativeAudio.config.output.bitrate = encoding.Bitrate; } } else if (encoding.EncodeRateType == AudioEncodeRateType.Quality) { // Bitrate of -1 signals quality targeting. nativeAudio.config.output.bitrate = -1; nativeAudio.config.output.quality = encoding.Quality; } // If this encoder supports compression level, pass it in. if (encoder.SupportsCompression) { nativeAudio.config.output.compression_level = encoding.Compression; } nativeAudio.config.output.dynamic_range_compression = encoding.Drc; nativeAudio.config.output.gain = encoding.Gain; } if (!string.IsNullOrEmpty(encoding.Name)) { IntPtr encodingNamePtr = Marshal.StringToHGlobalAnsi(encoding.Name); nativeAudio.config.output.name = encodingNamePtr; allocatedMemory.Add(encodingNamePtr); } nativeAudio.padding = new byte[MarshalingConstants.AudioPaddingBytes]; return nativeAudio; }
/* * TODO: This conversion class needs to be finished off before libencode will work. */ /// <summary> /// Get an EncodeJob model for a LibHB Encode. /// </summary> /// <param name="task"> /// The task. /// </param> /// <returns> /// An Interop.EncodeJob model. /// </returns> public static EncodeJob GetEncodeJob(QueueTask task) { // Sanity Checking if (task == null || task.Task == null) { return null; } // The current Job Configuration EncodeTask work = task.Task; // Which will be converted to this EncodeJob Model. EncodeJob job = new EncodeJob(); EncodingProfile profile = new EncodingProfile(); job.EncodingProfile = profile; profile.Anamorphic = work.Anamorphic; profile.AudioEncodings = new List<AudioEncoding>(); job.ChosenAudioTracks = new List<int>(); foreach (AudioTrack track in work.AudioTracks) { AudioEncoding newTrack = new AudioEncoding { Bitrate = track.Bitrate, Drc = track.DRC, Gain = track.Gain, Encoder = Converters.GetCliAudioEncoder(track.Encoder), InputNumber = track.Track.HasValue ? track.Track.Value : 0, Mixdown = Converters.GetCliMixDown(track.MixDown), SampleRateRaw = GetSampleRateRaw(track.SampleRate), }; profile.AudioEncodings.Add(newTrack); if (track.Track != null) { job.ChosenAudioTracks.Add(track.Track.Value); } } profile.Cropping = new Cropping { Top = work.Cropping.Top, Bottom = work.Cropping.Bottom, Left = work.Cropping.Left, Right = work.Cropping.Right }; profile.CroppingType = CroppingType.Custom; // TODO deal with this better profile.CustomDecomb = work.CustomDecomb; profile.CustomDeinterlace = work.CustomDeinterlace; profile.CustomDenoise = work.CustomDenoise; profile.CustomDetelecine = work.CustomDetelecine; profile.Deblock = work.Deblock; profile.Decomb = work.Decomb; profile.Deinterlace = work.Deinterlace; profile.Denoise = work.Denoise; profile.Detelecine = work.Detelecine; profile.DisplayWidth = work.DisplayWidth.HasValue ? int.Parse(Math.Round(work.DisplayWidth.Value, 0).ToString()) : 0; profile.Framerate = work.Framerate.HasValue ? work.Framerate.Value : 0; profile.Grayscale = work.Grayscale; profile.Height = work.Height.HasValue ? work.Height.Value : 0; profile.IPod5GSupport = work.IPod5GSupport; profile.IncludeChapterMarkers = work.IncludeChapterMarkers; profile.KeepDisplayAspect = work.KeepDisplayAspect; profile.LargeFile = work.LargeFile; profile.MaxHeight = work.MaxHeight.HasValue ? work.MaxHeight.Value : 0; profile.MaxWidth = work.MaxWidth.HasValue ? work.MaxWidth.Value : 0; profile.Modulus = work.Modulus.HasValue ? work.Modulus.Value : 16; profile.Optimize = work.OptimizeMP4; switch (work.OutputFormat) { case OutputFormat.Mp4: case OutputFormat.M4V: profile.OutputFormat = Container.Mp4; break; case OutputFormat.Mkv: profile.OutputFormat = Container.Mkv; break; } profile.ConstantFramerate = work.FramerateMode == FramerateMode.CFR; profile.PixelAspectX = work.PixelAspectX; profile.PixelAspectY = work.PixelAspectY; switch (work.OutputFormat) { case OutputFormat.Mp4: profile.PreferredExtension = OutputExtension.Mp4; break; case OutputFormat.M4V: profile.PreferredExtension = OutputExtension.M4v; break; } profile.Quality = work.Quality.HasValue ? work.Quality.Value : 0; profile.UseDisplayWidth = true; profile.VideoBitrate = work.VideoBitrate.HasValue ? work.VideoBitrate.Value : 0; profile.VideoEncodeRateType = work.VideoEncodeRateType; profile.VideoEncoder = Converters.GetVideoEncoder(work.VideoEncoder); profile.Width = work.Width.HasValue ? work.Width.Value : 0; profile.X264Options = work.AdvancedEncoderOptions; if (work.PointToPointMode == PointToPointMode.Chapters) { job.ChapterStart = work.StartPoint; job.ChapterEnd = work.EndPoint; } job.Angle = work.Angle; job.EncodingProfile = profile; if (work.PointToPointMode == PointToPointMode.Frames) { job.FramesEnd = work.EndPoint; job.FramesStart = work.StartPoint; } job.CustomChapterNames = work.ChapterNames.Select(item => item.ChapterName).ToList(); job.UseDefaultChapterNames = work.IncludeChapterMarkers; job.OutputPath = work.Destination; switch (work.PointToPointMode) { case PointToPointMode.Chapters: job.RangeType = VideoRangeType.Chapters; break; case PointToPointMode.Seconds: job.RangeType = VideoRangeType.Seconds; break; case PointToPointMode.Frames: job.RangeType = VideoRangeType.Frames; break; } if (work.PointToPointMode == PointToPointMode.Seconds) { job.SecondsEnd = work.EndPoint; job.SecondsStart = work.StartPoint; } job.SourcePath = work.Source; // job.SourceType = work.Type; job.Title = work.Title; // TODO Setup subtitles job.Subtitles = new Subtitles { SourceSubtitles = new List<SourceSubtitle>(), SrtSubtitles = new List<SrtSubtitle>() }; //foreach (SubtitleTrack track in work.SubtitleTracks) //{ // // TODO //} return job; }
public AudioEncodingViewModel(AudioEncoding audioEncoding, Title selectedTitle, List<int> chosenAudioTracks, string containerName, AudioPanelViewModel audioPanelVM) { this.initializing = true; this.audioPanelVM = audioPanelVM; this.targetStreams = new ObservableCollection<TargetStreamViewModel>(); this.targetStreamIndex = audioEncoding.InputNumber; this.SetChosenTracks(chosenAudioTracks, selectedTitle); this.audioEncoders = new List<AudioEncoderViewModel>(); this.mixdownChoices = new List<MixdownViewModel>(); this.containerName = containerName; this.RefreshEncoderChoices(); HBAudioEncoder hbAudioEncoder = Encoders.GetAudioEncoder(audioEncoding.Encoder); if (hbAudioEncoder.IsPassthrough) { this.selectedAudioEncoder = this.audioEncoders[0]; this.selectedPassthrough = audioEncoding.Encoder; } else { this.selectedAudioEncoder = this.audioEncoders.Skip(1).FirstOrDefault(e => e.Encoder.ShortName == audioEncoding.Encoder); this.selectedPassthrough = "copy"; } if (this.selectedAudioEncoder == null) { this.selectedAudioEncoder = this.audioEncoders[1]; } this.RefreshMixdownChoices(); this.RefreshBitrateChoices(); this.RefreshSampleRateChoices(); this.SelectMixdown(Encoders.GetMixdown(audioEncoding.Mixdown)); this.sampleRate = audioEncoding.SampleRateRaw; if (!this.HBAudioEncoder.SupportsQuality) { this.encodeRateType = AudioEncodeRateType.Bitrate; } else { this.encodeRateType = audioEncoding.EncodeRateType; } this.audioQuality = audioEncoding.Quality; if (audioEncoding.Compression >= 0) { this.audioCompression = audioEncoding.Compression; } else { this.audioCompression = this.HBAudioEncoder.DefaultCompression; } this.selectedBitrate = this.BitrateChoices.SingleOrDefault(b => b.Bitrate == audioEncoding.Bitrate); if (this.selectedBitrate == null) { this.selectedBitrate = this.BitrateChoices.First(); } this.gain = audioEncoding.Gain; this.drc = audioEncoding.Drc; this.passthroughIfPossible = audioEncoding.PassthroughIfPossible; this.name = audioEncoding.Name; Messenger.Default.Register<SelectedTitleChangedMessage>( this, message => { this.RefreshMixdownChoices(); this.RefreshBitrateChoices(); this.RefreshDrc(); }); Messenger.Default.Register<AudioInputChangedMessage>( this, message => { this.RefreshMixdownChoices(); this.RefreshBitrateChoices(); this.RefreshDrc(); }); Messenger.Default.Register<OptionsChangedMessage>( this, message => { this.RaisePropertyChanged(() => this.NameVisible); }); Messenger.Default.Register<ContainerChangedMessage>( this, message => { this.containerName = message.ContainerName; this.RefreshEncoderChoices(); }); this.initializing = false; }
/// <summary> /// Get an EncodeJob model for a LibHB Encode. /// </summary> /// <param name="task"> /// The task. /// </param> /// <returns> /// An Interop.EncodeJob model. /// </returns> public static EncodeJob GetEncodeJob(EncodeTask task) { // The current Job Configuration EncodeTask work = task; // Which will be converted to this EncodeJob Model. EncodeJob job = new EncodeJob(); EncodingProfile profile = new EncodingProfile(); job.EncodingProfile = profile; // Audio Settings profile.AudioEncodings = new List<AudioEncoding>(); job.ChosenAudioTracks = new List<int>(); foreach (AudioTrack track in work.AudioTracks) { AudioEncoding newTrack = new AudioEncoding { Bitrate = track.Bitrate, Drc = track.DRC, Gain = track.Gain, Encoder = Converters.GetCliAudioEncoder(track.Encoder), InputNumber = track.Track.HasValue ? track.Track.Value : 0, Mixdown = Converters.GetCliMixDown(track.MixDown), SampleRateRaw = GetSampleRateRaw(track.SampleRate), }; profile.AudioEncodings.Add(newTrack); if (track.Track != null) { job.ChosenAudioTracks.Add(track.Track.Value); } } // Title Settings job.OutputPath = work.Destination; job.SourcePath = work.Source; job.Title = work.Title; // job.SourceType = work.Type; switch (work.PointToPointMode) { case PointToPointMode.Chapters: job.RangeType = VideoRangeType.Chapters; break; case PointToPointMode.Seconds: job.RangeType = VideoRangeType.Seconds; break; case PointToPointMode.Frames: job.RangeType = VideoRangeType.Frames; break; } if (work.PointToPointMode == PointToPointMode.Seconds) { job.SecondsEnd = work.EndPoint; job.SecondsStart = work.StartPoint; } if (work.PointToPointMode == PointToPointMode.Chapters) { job.ChapterStart = work.StartPoint; job.ChapterEnd = work.EndPoint; } if (work.PointToPointMode == PointToPointMode.Frames) { job.FramesEnd = work.EndPoint; job.FramesStart = work.StartPoint; } job.Angle = work.Angle; job.EncodingProfile = profile; // Output Settings profile.IPod5GSupport = work.IPod5GSupport; profile.Optimize = work.OptimizeMP4; switch (work.OutputFormat) { case OutputFormat.Mp4: case OutputFormat.M4V: profile.OutputFormat = Container.Mp4; break; case OutputFormat.Mkv: profile.OutputFormat = Container.Mkv; break; } // Picture Settings profile.Anamorphic = work.Anamorphic; profile.Cropping = new Cropping { Top = work.Cropping.Top, Bottom = work.Cropping.Bottom, Left = work.Cropping.Left, Right = work.Cropping.Right }; profile.CroppingType = CroppingType.Custom; // TODO deal with this better profile.DisplayWidth = work.DisplayWidth.HasValue ? int.Parse(Math.Round(work.DisplayWidth.Value, 0).ToString()) : 0; profile.PixelAspectX = work.PixelAspectX; profile.PixelAspectY = work.PixelAspectY; profile.Height = work.Height.HasValue ? work.Height.Value : 0; profile.KeepDisplayAspect = work.KeepDisplayAspect; profile.MaxHeight = work.MaxHeight.HasValue ? work.MaxHeight.Value : 0; profile.MaxWidth = work.MaxWidth.HasValue ? work.MaxWidth.Value : 0; profile.Modulus = work.Modulus.HasValue ? work.Modulus.Value : 16; profile.UseDisplayWidth = true; profile.Width = work.Width.HasValue ? work.Width.Value : 0; // Filter Settings profile.CustomDecomb = work.CustomDecomb; profile.CustomDeinterlace = work.CustomDeinterlace; profile.CustomDenoise = work.CustomDenoise; profile.CustomDetelecine = work.CustomDetelecine; if (work.Deblock > 4) profile.Deblock = work.Deblock; profile.Decomb = work.Decomb; profile.Deinterlace = work.Deinterlace; profile.Denoise = work.Denoise; profile.Detelecine = work.Detelecine; profile.Grayscale = work.Grayscale; // Video Settings profile.Framerate = work.Framerate.HasValue ? work.Framerate.Value : 0; profile.ConstantFramerate = work.FramerateMode == FramerateMode.CFR; profile.Quality = work.Quality.HasValue ? work.Quality.Value : 0; profile.VideoBitrate = work.VideoBitrate.HasValue ? work.VideoBitrate.Value : 0; profile.VideoEncodeRateType = work.VideoEncodeRateType; profile.VideoEncoder = Converters.GetVideoEncoder(work.VideoEncoder); profile.H264Level = work.H264Level; profile.X264Profile = work.H264Profile.ToString().ToLower().Replace(" ", string.Empty); // TODO change these away from strings. profile.X264Preset = work.X264Preset.ToString().ToLower().Replace(" ", string.Empty); profile.X264Tunes = new List<string>(); if (work.X264Tune != x264Tune.None) { profile.X264Tunes.Add(work.X264Tune.ToString().ToLower().Replace(" ", string.Empty)); } if (work.FastDecode) { profile.X264Tunes.Add("fastdecode"); } // Chapter Markers profile.IncludeChapterMarkers = work.IncludeChapterMarkers; job.CustomChapterNames = work.ChapterNames.Select(item => item.ChapterName).ToList(); job.UseDefaultChapterNames = work.IncludeChapterMarkers; // Advanced Settings profile.X264Options = work.AdvancedEncoderOptions; // Subtitles job.Subtitles = new Subtitles { SourceSubtitles = new List<SourceSubtitle>(), SrtSubtitles = new List<SrtSubtitle>() }; foreach (SubtitleTrack track in work.SubtitleTracks) { if (track.IsSrtSubtitle) { job.Subtitles.SrtSubtitles.Add( new SrtSubtitle { CharacterCode = track.SrtCharCode, Default = track.Default, FileName = track.SrtFileName, LanguageCode = track.SrtLang, Offset = track.SrtOffset }); } else { if (track.SourceTrack != null) { job.Subtitles.SourceSubtitles.Add( new SourceSubtitle { BurnedIn = track.Burned, Default = track.Default, Forced = track.Forced, TrackNumber = track.SourceTrack.TrackNumber }); } } } return job; }
/// <summary> /// Applies an audio encoding to a native audio encoding base structure. /// </summary> /// <param name="encoding">The encoding to apply.</param> /// <param name="baseStruct">The base native structure.</param> /// <param name="outputTrack">The output track number (0-based).</param> /// <param name="allocatedMemory">The collection of allocated memory.</param> /// <returns>The resulting native audio structure.</returns> private hb_audio_s ConvertAudioBack(AudioEncoding encoding, hb_audio_s baseStruct, int outputTrack, List<IntPtr> allocatedMemory) { hb_audio_s nativeAudio = baseStruct; nativeAudio.config.output.track = outputTrack; if (encoding.Encoder == AudioEncoder.Passthrough) { // If we've been given a general "Passthrough" codec, see if it's valid for this input track. uint audioCodec = baseStruct.config.input.codec & NativeConstants.HB_ACODEC_PASS_MASK; if (audioCodec > 0) { // We can do passthrough for this input. //nativeAudio.config.output.codec = NativeConstants.HB_ACODEC_PASS_MASK | NativeConstants.HB_ACODEC_PASS_FLAG; nativeAudio.config.output.codec = audioCodec | NativeConstants.HB_ACODEC_PASS_FLAG; } else { // We can't do passthrough for this input. Set it to a DTS passthrough, which will cause the track to be dropped. nativeAudio.config.output.codec = NativeConstants.HB_ACODEC_DCA_PASS; } } else { nativeAudio.config.output.codec = Converters.AudioEncoderToNative(encoding.Encoder); } if (!Utilities.IsPassthrough(encoding.Encoder)) { nativeAudio.config.output.bitrate = encoding.Bitrate; nativeAudio.config.output.dynamic_range_compression = encoding.Drc; nativeAudio.config.output.gain = encoding.Gain; if (encoding.Mixdown == Mixdown.Auto) { nativeAudio.config.output.mixdown = HBFunctions.hb_get_default_mixdown(nativeAudio.config.output.codec, nativeAudio.config.input.channel_layout); } else { nativeAudio.config.output.mixdown = Converters.MixdownToNative(encoding.Mixdown); } if (encoding.SampleRateRaw == 0) { nativeAudio.config.output.samplerate = nativeAudio.config.input.samplerate; } else { nativeAudio.config.output.samplerate = encoding.SampleRateRaw; } } if (!string.IsNullOrEmpty(encoding.Name)) { IntPtr encodingNamePtr = Marshal.StringToHGlobalAnsi(encoding.Name); nativeAudio.config.output.name = encodingNamePtr; allocatedMemory.Add(encodingNamePtr); } nativeAudio.padding = new byte[MarshalingConstants.AudioPaddingBytes]; return nativeAudio; }
/// <summary> /// Applies an audio encoding to a native audio encoding base structure. /// </summary> /// <param name="encoding">The encoding to apply.</param> /// <param name="baseStruct">The base native structure.</param> /// <param name="outputTrack">The output track number (0-based).</param> /// <param name="allocatedMemory">The collection of allocated memory.</param> /// <returns>The resulting native audio structure.</returns> private hb_audio_s ConvertAudioBack(AudioEncoding encoding, hb_audio_s baseStruct, int outputTrack, List<IntPtr> allocatedMemory) { hb_audio_s nativeAudio = baseStruct; HBAudioEncoder encoder = Encoders.GetAudioEncoder(encoding.Encoder); if (encoder == null) { throw new InvalidOperationException("Could not find audio encoder " + encoding.Name); } bool isPassthrough = encoder.IsPassthrough; HBAudioEncoder inputCodec = Encoders.GetAudioEncoder((int)baseStruct.config.input.codec); uint outputCodec = (uint)encoder.Id; if (encoding.PassthroughIfPossible && (encoder.Id == baseStruct.config.input.codec || inputCodec != null && (inputCodec.ShortName.ToLowerInvariant().Contains("aac") && encoder.ShortName.ToLowerInvariant().Contains("aac") || inputCodec.ShortName.ToLowerInvariant().Contains("mp3") && encoder.ShortName.ToLowerInvariant().Contains("mp3"))) && (inputCodec.Id & NativeConstants.HB_ACODEC_PASS_MASK) > 0) { outputCodec = baseStruct.config.input.codec | NativeConstants.HB_ACODEC_PASS_FLAG; isPassthrough = true; } nativeAudio.config.output.track = outputTrack; nativeAudio.config.output.codec = outputCodec; nativeAudio.config.output.compression_level = -1; nativeAudio.config.output.samplerate = nativeAudio.config.input.samplerate; nativeAudio.config.output.dither_method = -1; if (!isPassthrough) { if (encoding.SampleRateRaw != 0) { nativeAudio.config.output.samplerate = encoding.SampleRateRaw; } HBMixdown mixdown = Encoders.GetMixdown(encoding.Mixdown); nativeAudio.config.output.mixdown = mixdown.Id; if (encoding.EncodeRateType == AudioEncodeRateType.Bitrate) { // Disable quality targeting. nativeAudio.config.output.quality = -3; if (encoding.Bitrate == 0) { // Bitrate of 0 means auto: choose the default for this codec, sample rate and mixdown. nativeAudio.config.output.bitrate = HBFunctions.hb_audio_bitrate_get_default( nativeAudio.config.output.codec, nativeAudio.config.output.samplerate, nativeAudio.config.output.mixdown); } else { nativeAudio.config.output.bitrate = encoding.Bitrate; } } else if (encoding.EncodeRateType == AudioEncodeRateType.Quality) { // Bitrate of -1 signals quality targeting. nativeAudio.config.output.bitrate = -1; nativeAudio.config.output.quality = encoding.Quality; } // If this encoder supports compression level, pass it in. if (encoder.SupportsCompression) { nativeAudio.config.output.compression_level = encoding.Compression; } nativeAudio.config.output.dynamic_range_compression = encoding.Drc; nativeAudio.config.output.gain = encoding.Gain; } if (!string.IsNullOrEmpty(encoding.Name)) { IntPtr encodingNamePtr = Marshal.StringToHGlobalAnsi(encoding.Name); nativeAudio.config.output.name = encodingNamePtr; allocatedMemory.Add(encodingNamePtr); } if (nativeAudio.padding == null) { nativeAudio.padding = new byte[MarshalingConstants.AudioPaddingBytes]; } return nativeAudio; }
/* * TODO: This conversion class needs to be finished off before libencode will work. */ /// <summary> /// Get an EncodeJob model for a LibHB Encode. /// </summary> /// <param name="task"> /// The task. /// </param> /// <returns> /// An Interop.EncodeJob model. /// </returns> public static EncodeJob GetEncodeJob(QueueTask task) { // Sanity Checking if (task == null || task.Task == null) { return null; } // The current Job Configuration EncodeTask work = task.Task; // Which will be converted to this EncodeJob Model. EncodeJob job = new EncodeJob(); EncodingProfile profile = new EncodingProfile(); job.EncodingProfile = profile; switch (work.Anamorphic) { case Model.Encoding.Anamorphic.Custom: profile.Anamorphic = Interop.Model.Encoding.Anamorphic.Custom; break; case Model.Encoding.Anamorphic.Strict: profile.Anamorphic = Interop.Model.Encoding.Anamorphic.Strict; break; case Model.Encoding.Anamorphic.Loose: profile.Anamorphic = Interop.Model.Encoding.Anamorphic.Loose; break; case Model.Encoding.Anamorphic.None: profile.Anamorphic = Interop.Model.Encoding.Anamorphic.None; break; } profile.AudioEncodings = new List<AudioEncoding>(); foreach (AudioTrack track in work.AudioTracks) { AudioEncoding newTrack = new AudioEncoding { Bitrate = track.Bitrate, Drc = track.DRC, Gain = track.Gain, //Encoder = track.Encoder, // InputNumber = track.Track, //Mixdown = track.MixDown, //SampleRateRaw = track.SampleRate }; profile.AudioEncodings.Add(newTrack); } profile.Cropping = new HandBrake.Interop.Model.Cropping { Top = work.Cropping.Top, Bottom = work.Cropping.Bottom, Left = work.Cropping.Left, Right = work.Cropping.Right }; profile.CustomCropping = true; profile.CustomDecomb = work.CustomDecomb; profile.CustomDeinterlace = work.CustomDeinterlace; profile.CustomDenoise = work.CustomDenoise; profile.CustomDetelecine = work.CustomDetelecine; profile.Deblock = work.Deblock; profile.Decomb = work.Decomb; profile.Deinterlace = work.Deinterlace; profile.Denoise = work.Denoise; profile.Detelecine = work.Detelecine; profile.DisplayWidth = work.DisplayWidth.HasValue ? int.Parse(Math.Round(work.DisplayWidth.Value, 0).ToString()) : 0; profile.Framerate = work.Framerate.HasValue ? work.Framerate.Value : 0; profile.Grayscale = work.Grayscale; profile.Height = work.Height.HasValue ? work.Height.Value : 0; profile.IPod5GSupport = work.IPod5GSupport; profile.IncludeChapterMarkers = work.IncludeChapterMarkers; profile.KeepDisplayAspect = work.KeepDisplayAspect; profile.LargeFile = work.LargeFile; profile.MaxHeight = work.MaxHeight.HasValue ? work.MaxHeight.Value : 0; profile.MaxWidth = work.MaxWidth.HasValue ? work.MaxWidth.Value : 0; profile.Modulus = work.Modulus.HasValue ? work.Modulus.Value : 16; profile.Optimize = work.OptimizeMP4; switch (work.OutputFormat) { case OutputFormat.Mp4: case OutputFormat.M4V: profile.OutputFormat = Interop.Model.Encoding.OutputFormat.Mp4; break; case OutputFormat.Mkv: profile.OutputFormat = Interop.Model.Encoding.OutputFormat.Mkv; break; } profile.PeakFramerate = work.FramerateMode == FramerateMode.PFR; profile.PixelAspectX = work.PixelAspectX; profile.PixelAspectY = work.PixelAspectY; switch (work.OutputFormat) { case OutputFormat.Mp4: profile.PreferredExtension = Interop.Model.Encoding.OutputExtension.Mp4; break; case OutputFormat.M4V: profile.PreferredExtension = Interop.Model.Encoding.OutputExtension.M4v; break; } profile.Quality = work.Quality.HasValue ? work.Quality.Value : 0; profile.UseDisplayWidth = true; profile.VideoBitrate = work.VideoBitrate.HasValue ? work.VideoBitrate.Value : 0; profile.VideoEncodeRateType = work.VideoEncodeRateType; switch (work.VideoEncoder) { case VideoEncoder.X264: profile.VideoEncoder = Interop.Model.Encoding.VideoEncoder.X264; break; case VideoEncoder.FFMpeg: profile.VideoEncoder = Interop.Model.Encoding.VideoEncoder.FFMpeg; break; case VideoEncoder.FFMpeg2: profile.VideoEncoder = Interop.Model.Encoding.VideoEncoder.FFMpeg; // TODO Fix This. break; case VideoEncoder.Theora: profile.VideoEncoder = Interop.Model.Encoding.VideoEncoder.Theora; break; } profile.Width = work.Width.HasValue ? work.Width.Value : 0; profile.X264Options = work.AdvancedEncoderOptions; if (work.PointToPointMode == PointToPointMode.Chapters) { job.ChapterStart = work.StartPoint; job.ChapterEnd = work.EndPoint; } job.Angle = work.Angle; job.EncodingProfile = profile; if (work.PointToPointMode == PointToPointMode.Frames) { job.FramesEnd = work.EndPoint; job.FramesStart = work.StartPoint; } job.OutputPath = work.Destination; switch (work.PointToPointMode) { case PointToPointMode.Chapters: job.RangeType = VideoRangeType.Chapters; break; case PointToPointMode.Seconds: job.RangeType = VideoRangeType.Seconds; break; case PointToPointMode.Frames: job.RangeType = VideoRangeType.Frames; break; } if (work.PointToPointMode == PointToPointMode.Seconds) { job.SecondsEnd = work.EndPoint; job.SecondsStart = work.StartPoint; } job.SourcePath = work.Source; // job.SourceType = work.Type; job.Title = work.Title; job.Subtitles = new Subtitles { SourceSubtitles = new List<SourceSubtitle>(), SrtSubtitles = new List<SrtSubtitle>() }; foreach (SubtitleTrack track in work.SubtitleTracks) { // TODO } return job; }
/// <summary> /// Applies an audio encoding to a native audio encoding base structure. /// </summary> /// <param name="encoding">The encoding to apply.</param> /// <param name="baseStruct">The base native structure.</param> /// <param name="outputTrack">The output track number (0-based).</param> /// <param name="allocatedMemory">The collection of allocated memory.</param> /// <returns>The resulting native audio structure.</returns> private hb_audio_s ConvertAudioBack(AudioEncoding encoding, hb_audio_s baseStruct, int outputTrack, List<IntPtr> allocatedMemory) { hb_audio_s nativeAudio = baseStruct; nativeAudio.config.output.track = outputTrack; nativeAudio.config.output.codec = Converters.AudioEncoderToNative(encoding.Encoder); if (!Utilities.IsPassthrough(encoding.Encoder)) { nativeAudio.config.output.bitrate = encoding.Bitrate; nativeAudio.config.output.dynamic_range_compression = encoding.Drc; nativeAudio.config.output.gain = encoding.Gain; if (encoding.Mixdown == Mixdown.Auto) { nativeAudio.config.output.mixdown = HBFunctions.hb_get_default_mixdown(nativeAudio.config.output.codec, nativeAudio.config.input.channel_layout); } else { nativeAudio.config.output.mixdown = Converters.MixdownToNative(encoding.Mixdown); } if (encoding.SampleRateRaw == 0) { nativeAudio.config.output.samplerate = nativeAudio.config.input.samplerate; } else { nativeAudio.config.output.samplerate = encoding.SampleRateRaw; } } if (!string.IsNullOrEmpty(encoding.Name)) { IntPtr encodingNamePtr = Marshal.StringToHGlobalAnsi(encoding.Name); nativeAudio.config.output.name = encodingNamePtr; allocatedMemory.Add(encodingNamePtr); } nativeAudio.padding = new byte[MarshalingConstants.AudioPaddingBytes]; return nativeAudio; }