/// <summary> /// Gets overall bitrate limits for the given audio encoder. /// </summary> /// <param name="encoder">The encoder to check.</param> /// <returns>The bitrate limits for the given encoder.</returns> /// <remarks>HandBrake does not supply an "overall" set of limits, only when you give it a specific /// mixdown and sample rate.</remarks> public static BitrateLimits GetAudioEncoderLimits(HBAudioEncoder encoder) { int low = 8; int high = 1536; switch (encoder.ShortName) { case "fdk_aac": low = 48; high = 1440; break; case "fdk_haac": low = 8; high = 256; break; case "av_aac": low = 32; high = 512; break; case "vorbis": low = 32; high = 1536; break; case "mp3": low = 32; high = 320; break; case "ac3": low = 48; high = 640; break; } return new BitrateLimits { Low = low, High = high }; }
/// <summary> /// Converts a native HB encoder structure to an Encoder model. /// </summary> /// <param name="encoder">The structure to convert.</param> /// <returns>The converted model.</returns> public static HBAudioEncoder NativeToAudioEncoder(hb_encoder_s encoder) { var result = new HBAudioEncoder { Id = encoder.codec, ShortName = encoder.short_name, DisplayName = encoder.name, CompatibleContainers = encoder.muxers }; result.QualityLimits = Encoders.GetAudioQualityLimits(encoder.codec); result.DefaultQuality = HBFunctions.hb_audio_quality_get_default((uint)encoder.codec); result.CompressionLimits = Encoders.GetAudioCompressionLimits(encoder.codec); result.DefaultCompression = HBFunctions.hb_audio_compression_get_default((uint)encoder.codec); return result; }
/// <summary> /// Sanitizes a mixdown given the output codec and input channel layout. /// </summary> /// <param name="mixdown">The desired mixdown.</param> /// <param name="encoder">The output encoder to be used.</param> /// <param name="layout">The input channel layout.</param> /// <returns>A sanitized mixdown value.</returns> public static HBMixdown SanitizeMixdown(HBMixdown mixdown, HBAudioEncoder encoder, ulong layout) { int sanitizedMixdown = HBFunctions.hb_mixdown_get_best((uint)encoder.Id, layout, mixdown.Id); return Mixdowns.Single(m => m.Id == sanitizedMixdown); }
/// <summary> /// Sanitizes an audio bitrate given the output codec, sample rate and mixdown. /// </summary> /// <param name="audioBitrate">The desired audio bitrate.</param> /// <param name="encoder">The output encoder to be used.</param> /// <param name="sampleRate">The output sample rate to be used.</param> /// <param name="mixdown">The mixdown to be used.</param> /// <returns>A sanitized audio bitrate.</returns> 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); }
/// <summary> /// Determines if the given encoder supports the given mixdown. /// </summary> /// <param name="mixdown">The mixdown to evaluate.</param> /// <param name="encoder">The encoder to evaluate.</param> /// <returns>True if the encoder supports the mixdown.</returns> public static bool MixdownHasCodecSupport(HBMixdown mixdown, HBAudioEncoder encoder) { return HBFunctions.hb_mixdown_has_codec_support(mixdown.Id, (uint) encoder.Id) > 0; }
/// <summary> /// Gets the default mixdown for the given audio encoder and channel layout. /// </summary> /// <param name="encoder">The output codec to be used.</param> /// <param name="layout">The input channel layout.</param> /// <returns>The default mixdown for the given codec and channel layout.</returns> 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); }
/// <summary> /// Gets the default audio bitrate for the given parameters. /// </summary> /// <param name="encoder">The encoder to use.</param> /// <param name="sampleRate">The sample rate to use.</param> /// <param name="mixdown">The mixdown to use.</param> /// <returns>The default bitrate for these parameters.</returns> public static int GetDefaultBitrate(HBAudioEncoder encoder, int sampleRate, HBMixdown mixdown) { return HBFunctions.hb_audio_bitrate_get_default((uint) encoder.Id, sampleRate, mixdown.Id); }
/// <summary> /// Gets the bitrate limits for the given audio codec, sample rate and mixdown. /// </summary> /// <param name="encoder">The audio encoder used.</param> /// <param name="sampleRate">The sample rate used (Hz).</param> /// <param name="mixdown">The mixdown used.</param> /// <returns>Limits on the audio bitrate for the given settings.</returns> 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 = low, High = high }; }
/// <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; }
/// <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> /// Converts a native HB encoder structure to an Encoder model. /// </summary> /// <param name="encoder">The structure to convert.</param> /// <returns>The converted model.</returns> public static HBAudioEncoder NativeToAudioEncoder(hb_encoder_s encoder) { var result = new HBAudioEncoder { Id = encoder.encoder, ShortName = encoder.short_name, DisplayName = encoder.human_readable_name, CompatibleContainers = Container.None }; if ((encoder.muxers & NativeConstants.HB_MUX_MKV) > 0) { result.CompatibleContainers = result.CompatibleContainers | Container.Mkv; } if ((encoder.muxers & NativeConstants.HB_MUX_MP4) > 0) { result.CompatibleContainers = result.CompatibleContainers | Container.Mp4; } result.QualityLimits = Encoders.GetAudioQualityLimits(encoder.encoder); result.DefaultQuality = HBFunctions.hb_get_default_audio_quality((uint)encoder.encoder); result.CompressionLimits = Encoders.GetAudioCompressionLimits(encoder.encoder); result.DefaultCompression = HBFunctions.hb_get_default_audio_compression((uint) encoder.encoder); return result; }
/// <summary> /// Finds the highest possible mixdown for a given audio encoder. /// </summary> /// <param name="audioEncoder">The audio encoder in question.</param> /// <returns>The highest possible mixdown for that audio encoder.</returns> public static int GetMaxMixdownIndex(HBAudioEncoder audioEncoder) { // To find best case scenario, pass in highest number of channels and 6-channel discrete mixdown. int maxMixdownId = HBFunctions.hb_get_best_mixdown((uint)audioEncoder.Id, NativeConstants.HB_INPUT_CH_LAYOUT_3F4R | NativeConstants.HB_INPUT_CH_LAYOUT_HAS_LFE, NativeConstants.HB_AMIXDOWN_6CH); for (int i = 0; i < Mixdowns.Count; i++) { if (Mixdowns[i].Id == maxMixdownId) { return i; } } return -1; }