/// <summary> /// Converts a native title to a Title object. /// </summary> /// <param name="title">The native title structure.</param> /// <returns>The managed Title object.</returns> private Title ConvertTitle(hb_title_s title) { var newTitle = new Title { TitleNumber = title.index, Resolution = new Size(title.width, title.height), ParVal = new Size(title.pixel_aspect_width, title.pixel_aspect_height), Duration = TimeSpan.FromSeconds(title.duration / 90000), AutoCropDimensions = new Cropping { Top = title.crop[0], Bottom = title.crop[1], Left = title.crop[2], Right = title.crop[3] }, AspectRatio = title.aspect, AngleCount = title.angle_count, VideoCodecName = title.video_codec_name, Framerate = ((double)title.rate) / title.rate_base }; switch (title.type) { case hb_title_type_anon.HB_STREAM_TYPE: newTitle.InputType = InputType.Stream; break; case hb_title_type_anon.HB_DVD_TYPE: newTitle.InputType = InputType.Dvd; break; case hb_title_type_anon.HB_BD_TYPE: newTitle.InputType = InputType.Bluray; break; } int currentSubtitleTrack = 1; List<hb_subtitle_s> subtitleList = InteropUtilities.ConvertList<hb_subtitle_s>(title.list_subtitle); foreach (hb_subtitle_s subtitle in subtitleList) { var newSubtitle = new Subtitle { TrackNumber = currentSubtitleTrack, Language = subtitle.lang, LanguageCode = subtitle.iso639_2 }; if (subtitle.format == hb_subtitle_s_subtype.PICTURESUB) { newSubtitle.SubtitleType = SubtitleType.Picture; } else if (subtitle.format == hb_subtitle_s_subtype.TEXTSUB) { newSubtitle.SubtitleType = SubtitleType.Text; } switch (subtitle.source) { case hb_subtitle_s_subsource.CC608SUB: newSubtitle.SubtitleSource = SubtitleSource.CC608; break; case hb_subtitle_s_subsource.CC708SUB: newSubtitle.SubtitleSource = SubtitleSource.CC708; break; case hb_subtitle_s_subsource.SRTSUB: newSubtitle.SubtitleSource = SubtitleSource.SRT; break; case hb_subtitle_s_subsource.SSASUB: newSubtitle.SubtitleSource = SubtitleSource.SSA; break; case hb_subtitle_s_subsource.TX3GSUB: newSubtitle.SubtitleSource = SubtitleSource.TX3G; break; case hb_subtitle_s_subsource.UTF8SUB: newSubtitle.SubtitleSource = SubtitleSource.UTF8; break; case hb_subtitle_s_subsource.VOBSUB: newSubtitle.SubtitleSource = SubtitleSource.VobSub; break; default: break; } newTitle.Subtitles.Add(newSubtitle); currentSubtitleTrack++; } int currentAudioTrack = 1; List<hb_audio_s> audioList = InteropUtilities.ConvertList<hb_audio_s>(title.list_audio); foreach (hb_audio_s audio in audioList) { var newAudio = new AudioTrack { TrackNumber = currentAudioTrack, Codec = Converters.NativeToAudioCodec(audio.config.input.codec), CodecId = audio.config.input.codec, Language = audio.config.lang.simple, LanguageCode = audio.config.lang.iso639_2, Description = audio.config.lang.description, ChannelLayout = audio.config.input.channel_layout, SampleRate = audio.config.input.samplerate, Bitrate = audio.config.input.bitrate }; newTitle.AudioTracks.Add(newAudio); currentAudioTrack++; } List<hb_chapter_s> chapterList = InteropUtilities.ConvertList<hb_chapter_s>(title.list_chapter); foreach (hb_chapter_s chapter in chapterList) { var newChapter = new Chapter { ChapterNumber = chapter.index, Duration = TimeSpan.FromSeconds(((double)chapter.duration) / 90000) }; newTitle.Chapters.Add(newChapter); } return newTitle; }
/// <summary> /// Determines if the given encoder is compatible with the given track. /// </summary> /// <param name="track">The audio track to examine.</param> /// <param name="encoder">The encoder to examine.</param> /// <returns>True if the given encoder is comatible with the given audio track.</returns> /// <remarks>Only works with passthrough encoders.</remarks> public static bool AudioEncoderIsCompatible(AudioTrack track, HBAudioEncoder encoder) { return (track.CodecId & encoder.Id) > 0; }
/// <summary> /// Determines if DRC can be applied to the given track with the given encoder. /// </summary> /// <param name="track">The track to apply DRC to.</param> /// <param name="encoder">The encoder to use for DRC.</param> /// <returns>True if DRC can be applied to the track with the given encoder.</returns> public static bool CanApplyDrc(AudioTrack track, HBAudioEncoder encoder) { return HBFunctions.hb_audio_can_apply_drc(track.CodecId, track.CodecParam, encoder.Id) > 0; }
public AudioOutputPreview GetAudioPreview(AudioTrack inputTrack, AudioEncodingViewModel audioVM) { HBAudioEncoder encoder = audioVM.HBAudioEncoder; var outputPreviewTrack = new AudioOutputPreview { Name = inputTrack.NoTrackDisplay, Encoder = encoder.DisplayName }; if (encoder.IsPassthrough) { // For passthrough encodes, we need to make sure the input track is of the right type if (!Encoders.AudioEncoderIsCompatible(inputTrack, encoder) && encoder.ShortName != "copy") { return null; } HBContainer container = Encoders.GetContainer(this.Profile.ContainerName); if (encoder.ShortName == "copy" && (inputTrack.Codec == AudioCodec.Dts || inputTrack.Codec == AudioCodec.DtsHD) && container.DefaultExtension == "mp4") { this.PassthroughWarningText = EncodingRes.DtsMp4Warning; this.PassthroughWarningVisible = true; return outputPreviewTrack; } } // Find out what the real mixdown, sample rate and bitrate will be. HBMixdown mixdown; int sampleRate, bitrate; if (encoder.ShortName == "copy") { if (Encoders.AudioEncoderIsCompatible(inputTrack, encoder)) { return outputPreviewTrack; } if (this.Profile.AudioEncoderFallback == null) { encoder = Encoders.AudioEncoders.First(a => !a.IsPassthrough); } else { encoder = Encoders.GetAudioEncoder(this.Profile.AudioEncoderFallback); } mixdown = Encoders.GetDefaultMixdown(encoder, inputTrack.ChannelLayout); sampleRate = 0; bitrate = 0; outputPreviewTrack.Encoder = encoder.DisplayName; } else { mixdown = audioVM.SelectedMixdown.Mixdown; sampleRate = audioVM.SampleRate; bitrate = audioVM.SelectedBitrate.Bitrate; } HBMixdown previewMixdown; previewMixdown = Encoders.SanitizeMixdown(mixdown, encoder, inputTrack.ChannelLayout); int previewSampleRate = sampleRate; if (previewSampleRate == 0) { previewSampleRate = inputTrack.SampleRate; } int previewBitrate = bitrate; if (previewBitrate == 0) { previewBitrate = Encoders.GetDefaultBitrate(encoder, previewSampleRate, previewMixdown); } else { previewBitrate = Encoders.SanitizeAudioBitrate(previewBitrate, encoder, previewSampleRate, previewMixdown); } outputPreviewTrack.Mixdown = previewMixdown.DisplayName; outputPreviewTrack.SampleRate = DisplayConversions.DisplaySampleRate(previewSampleRate); if (audioVM.EncodeRateType == AudioEncodeRateType.Bitrate) { if (previewBitrate >= 0) { outputPreviewTrack.Quality = previewBitrate + " kbps"; } else { outputPreviewTrack.Quality = string.Empty; } } else { outputPreviewTrack.Quality = "CQ " + audioVM.AudioQuality; } var modifiers = new List<string>(); if (audioVM.Gain != 0) { modifiers.Add(string.Format("{0}{1} dB", audioVM.Gain > 0 ? "+" : string.Empty, audioVM.Gain)); } if (audioVM.Drc != 0) { modifiers.Add("DRC " + audioVM.Drc.ToString()); } outputPreviewTrack.Modifiers = string.Join(", ", modifiers); return outputPreviewTrack; }