// -------------------------------------------------------------------------------------------------------------------- // // This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. // // // The encoders. // // -------------------------------------------------------------------------------------------------------------------- namespace HandBrake.Interop.Interop { using System.Collections.Generic; using System.Linq; using HandBrake.Interop.Interop.HbLib; using HandBrake.Interop.Interop.Helpers; using HandBrake.Interop.Interop.Model; using HandBrake.Interop.Interop.Model.Encoding; /// /// The encoders. /// public static class HandBrakeEncoderHelpers { /// /// The audio encoders. /// private static List audioEncoders; /// /// The video encoders. /// private static List videoEncoders; /// /// Video framerates in pts. /// private static List videoFramerates; /// /// List of HandBrake mixdowns. /// private static List mixdowns; /// /// List of HandBrake containers. /// private static List containers; /// /// The audio bitrates. /// private static List audioBitrates; /// /// Audio sample rates in Hz. /// private static List audioSampleRates; /// /// Initializes static members of the HandBrakeEncoderHelpers class. /// static HandBrakeEncoderHelpers() { HandBrakeUtils.EnsureGlobalInit(); } /// /// Gets a list of supported audio encoders. /// public static List AudioEncoders { get { if (audioEncoders == null) { audioEncoders = InteropUtilities.ToListFromIterator(HBFunctions.hb_audio_encoder_get_next, HandBrakeUnitConversionHelpers.NativeToAudioEncoder); } return audioEncoders; } } /// /// Gets a list of supported video encoders. /// public static List VideoEncoders { get { if (videoEncoders == null) { videoEncoders = InteropUtilities.ToListFromIterator(HBFunctions.hb_video_encoder_get_next, HandBrakeUnitConversionHelpers.NativeToVideoEncoder); } return videoEncoders; } } /// /// Gets a list of supported video framerates (in pts). /// public static List VideoFramerates { get { if (videoFramerates == null) { videoFramerates = InteropUtilities.ToListFromIterator(HBFunctions.hb_video_framerate_get_next, HandBrakeUnitConversionHelpers.NativeToRate); } return videoFramerates; } } /// /// Gets a list of supported mixdowns. /// public static List Mixdowns { get { if (mixdowns == null) { mixdowns = InteropUtilities.ToListFromIterator(HBFunctions.hb_mixdown_get_next, HandBrakeUnitConversionHelpers.NativeToMixdown); } return mixdowns; } } /// /// Gets a list of supported audio bitrates. /// public static List AudioBitrates { get { if (audioBitrates == null) { audioBitrates = InteropUtilities.ToListFromIterator(HBFunctions.hb_audio_bitrate_get_next, b => b.rate); } return audioBitrates; } } /// /// Gets a list of supported audio sample rates (in Hz). /// public static List AudioSampleRates { get { if (audioSampleRates == null) { audioSampleRates = InteropUtilities.ToListFromIterator(HBFunctions.hb_audio_samplerate_get_next, HandBrakeUnitConversionHelpers.NativeToRate); } return audioSampleRates; } } /// /// Gets a list of supported containers. /// public static List Containers { get { if (containers == null) { containers = InteropUtilities.ToListFromIterator(HBFunctions.hb_container_get_next, HandBrakeUnitConversionHelpers.NativeToContainer); } return containers; } } /// /// Gets a value indicating whether SRT subtitles can be burnt in. /// public static bool CanBurnSrt { get { return HBFunctions.hb_subtitle_can_burn((int)hb_subtitle_s_subsource.SRTSUB) > 0; } } /// /// Gets the audio encoder with the specified short name. /// /// /// The name of the audio encoder. /// /// /// The requested audio encoder. /// public static HBAudioEncoder GetAudioEncoder(string shortName) { return AudioEncoders.SingleOrDefault(e => e.ShortName == shortName); } /// /// Gets the audio encoder with the specified codec ID. /// /// /// The ID of the audio encoder. /// /// /// The requested audio encoder. /// public static HBAudioEncoder GetAudioEncoder(int codecId) { return AudioEncoders.SingleOrDefault(e => e.Id == codecId); } /// /// Gets the video encoder with the specified short name. /// /// /// The name of the video encoder. /// /// /// The requested video encoder. /// public static HBVideoEncoder GetVideoEncoder(string shortName) { return VideoEncoders.SingleOrDefault(e => e.ShortName == shortName); } /// /// Gets the mixdown with the specified short name. /// /// /// The name of the mixdown. /// /// /// The requested mixdown. /// public static HBMixdown GetMixdown(string shortName) { return Mixdowns.SingleOrDefault(m => m.ShortName == shortName); } /// /// Gets the mixdown with the specified ID. /// /// The mixdown ID. /// The requested mixdown. public static HBMixdown GetMixdown(int id) { return Mixdowns.SingleOrDefault(m => m.Id == id); } /// /// Gets the container with the specified short name. /// /// /// The name of the container. /// /// /// The requested container. /// public static HBContainer GetContainer(string shortName) { return Containers.SingleOrDefault(c => c.ShortName == shortName); } /// /// Returns true if the subtitle source type can be set to forced only. /// /// /// The subtitle source type (SSA, VobSub, etc) /// /// /// True if the subtitle source type can be set to forced only. /// public static bool SubtitleCanSetForcedOnly(int source) { return HBFunctions.hb_subtitle_can_force(source) > 0; } /// /// Returns true if the subtitle source type can be burned in. /// /// /// The subtitle source type (SSA, VobSub, etc) /// /// /// True if the subtitle source type can be burned in. /// public static bool SubtitleCanBurn(int source) { return HBFunctions.hb_subtitle_can_burn(source) > 0; } /// /// Returns true if the subtitle type can be passed through using the given muxer. /// /// /// The subtitle source type (SSA, VobSub, etc) /// /// /// The ID of the muxer. /// /// /// True if the subtitle type can be passed through with the given muxer. /// public static bool SubtitleCanPassthrough(int subtitleSourceType, int muxer) { return HBFunctions.hb_subtitle_can_pass(subtitleSourceType, muxer) > 0; } /// /// Gets the subtitle source type's name. /// /// /// The subtitle source type (SSA, VobSub, etc). /// /// /// The name of the subtitle source. /// public static string GetSubtitleSourceName(int source) { switch ((hb_subtitle_s_subsource)source) { case hb_subtitle_s_subsource.CC608SUB: return "CC608"; case hb_subtitle_s_subsource.CC708SUB: return "CC708"; case hb_subtitle_s_subsource.SRTSUB: return "SRT"; case hb_subtitle_s_subsource.SSASUB: return "SSA"; case hb_subtitle_s_subsource.TX3GSUB: return "TX3G"; case hb_subtitle_s_subsource.UTF8SUB: return "UTF8"; case hb_subtitle_s_subsource.VOBSUB: return "VobSub"; case hb_subtitle_s_subsource.PGSSUB: return "PGS"; default: return string.Empty; } } /// /// Determines if the given encoder is compatible with the given track. /// /// /// The codec Id. /// /// /// The encoder to examine. /// /// /// True if the given encoder is comatible with the given audio track. /// /// /// Only works with passthrough encoders. /// public static bool AudioEncoderIsCompatible(int codecId, HBAudioEncoder encoder) { return (codecId & encoder.Id) > 0; } /// /// Determines if the given mixdown supports the given channel layout. /// /// /// The mixdown to evaluate. /// /// /// The channel layout to evaluate. /// /// /// True if the mixdown supports the given channel layout. /// public static bool MixdownHasRemixSupport(HBMixdown mixdown, ulong layout) { return HBFunctions.hb_mixdown_has_remix_support(mixdown.Id, layout) > 0; } /// /// Determines if the given encoder supports the given mixdown. /// /// /// The mixdown to evaluate. /// /// /// The encoder to evaluate. /// /// /// True if the encoder supports the mixdown. /// public static bool MixdownHasCodecSupport(HBMixdown mixdown, HBAudioEncoder encoder) { return HBFunctions.hb_mixdown_has_codec_support(mixdown.Id, (uint)encoder.Id) > 0; } /// /// Determines if a mixdown is available for a given track and encoder. /// /// /// The mixdown to evaluate. /// /// /// The encoder to evaluate. /// /// channel layout of the source track /// True if available. public static bool MixdownIsSupported(HBMixdown mixdown, HBAudioEncoder encoder, long channelLayout) { return HBFunctions.hb_mixdown_is_supported(mixdown.Id, (uint)encoder.Id, (uint)channelLayout) > 0; } /// /// Determines if DRC can be applied to the given track with the given encoder. /// /// /// The track Number. /// /// /// The encoder to use for DRC. /// /// /// The title. /// /// /// True if DRC can be applied to the track with the given encoder. /// public static bool CanApplyDrc(int trackNumber, HBAudioEncoder encoder, int title) { return HBFunctions.hb_audio_can_apply_drc2(HandBrakeInstanceManager.LastScanHandle, title, trackNumber, encoder.Id) > 0; } /// /// Determines if the given input audio codec can be passed through. /// /// /// The input codec to consider. /// /// /// True if the codec can be passed through. /// public static bool CanPassthroughAudio(int codecId) { return (codecId & NativeConstants.HB_ACODEC_PASS_MASK) > 0; } /// /// Sanitizes a mixdown given the output codec and input channel layout. /// /// /// The desired mixdown. /// /// /// The output encoder to be used. /// /// /// The input channel layout. /// /// /// A sanitized mixdown value. /// public static HBMixdown SanitizeMixdown(HBMixdown mixdown, HBAudioEncoder encoder, ulong layout) { if (mixdown == null) { return null; } int sanitizedMixdown = HBFunctions.hb_mixdown_get_best((uint)encoder.Id, layout, mixdown.Id); if (sanitizedMixdown != -1) { return Mixdowns.Single(m => m.Id == sanitizedMixdown); } return Mixdowns.FirstOrDefault(); // "none" } /// /// Gets the default mixdown for the given audio encoder and channel layout. /// /// /// The output codec to be used. /// /// /// The input channel layout. /// /// /// The default mixdown for the given codec and channel layout. /// public static HBMixdown GetDefaultMixdown(HBAudioEncoder encoder, ulong layout) { int defaultMixdown = HBFunctions.hb_mixdown_get_default((uint)encoder.Id, layout); return Mixdowns.Single(m => m.Id == defaultMixdown); } /// /// Sanitizes the given sample rate for the given encoder. /// /// The encoder. /// The sample rate to sanitize. /// The sanitized sample rate. public static int SanitizeSampleRate(HBAudioEncoder encoder, int sampleRate) { return HBFunctions.hb_audio_samplerate_find_closest(sampleRate, (uint)encoder.Id); } /// /// Gets the bitrate limits for the given audio codec, sample rate and mixdown. /// /// /// The audio encoder used. /// /// /// The sample rate used (Hz). /// /// /// The mixdown used. /// /// /// Limits on the audio bitrate for the given settings. /// public static BitrateLimits GetBitrateLimits(HBAudioEncoder encoder, int sampleRate, HBMixdown mixdown) { int low = 0; int high = 0; HBFunctions.hb_audio_bitrate_get_limits((uint)encoder.Id, sampleRate, mixdown.Id, ref low, ref high); return new BitrateLimits(low, high); } /// /// Gets the video quality limits for the given video codec. /// /// /// The video encoder to check. /// /// /// Limits on the video quality for the encoder. /// public static VideoQualityLimits GetVideoQualityLimits(HBVideoEncoder encoder) { float low = 0; float high = 0; float granularity = 0; int direction = 0; HBFunctions.hb_video_quality_get_limits((uint)encoder.Id, ref low, ref high, ref granularity, ref direction); return new VideoQualityLimits(low, high, granularity, direction == 0); } /// /// Sanitizes an audio bitrate given the output codec, sample rate and mixdown. /// /// /// The desired audio bitrate. /// /// /// The output encoder to be used. /// /// /// The output sample rate to be used. /// /// /// The mixdown to be used. /// /// /// A sanitized audio bitrate. /// public static int SanitizeAudioBitrate(int audioBitrate, HBAudioEncoder encoder, int sampleRate, HBMixdown mixdown) { return HBFunctions.hb_audio_bitrate_get_best((uint)encoder.Id, audioBitrate, sampleRate, mixdown.Id); } /// /// Gets the default audio bitrate for the given parameters. /// /// /// The encoder to use. /// /// /// The sample rate to use. /// /// /// The mixdown to use. /// /// /// The default bitrate for these parameters. /// public static int GetDefaultBitrate(HBAudioEncoder encoder, int sampleRate, HBMixdown mixdown) { return HBFunctions.hb_audio_bitrate_get_default((uint)encoder.Id, sampleRate, mixdown.Id); } /// /// Gets limits on audio quality for a given encoder. /// /// /// The audio encoder ID. /// /// /// Limits on the audio quality for the given encoder. /// public static RangeLimits GetAudioQualityLimits(int encoderId) { float low = 0, high = 0, granularity = 0; int direction = 0; HBFunctions.hb_audio_quality_get_limits((uint)encoderId, ref low, ref high, ref granularity, ref direction); return new RangeLimits(direction == 0, granularity, high, low); } /// /// Gets limits on audio compression for a given encoder. /// /// /// The audio encoder ID. /// /// /// Limits on the audio compression for the given encoder. /// public static RangeLimits GetAudioCompressionLimits(int encoderId) { float low = 0, high = 0, granularity = 0; int direction = 0; HBFunctions.hb_audio_compression_get_limits((uint)encoderId, ref low, ref high, ref granularity, ref direction); return new RangeLimits(direction == 0, granularity, high, low); } /// /// The get default quality. /// /// /// The encoder. /// /// /// The . /// public static double GetDefaultQuality(HBAudioEncoder encoder) { return HBFunctions.hb_audio_quality_get_default((uint)encoder.Id); } /// /// The get default audio compression. /// /// /// The encoder. /// /// /// The . /// public static double GetDefaultAudioCompression(HBAudioEncoder encoder) { return HBFunctions.hb_audio_compression_get_default((uint)encoder.Id); } } }